-
April 14th, 2013, 09:33 AM
#16
Re: deployment catch 22
One more hint: After correcting your InternetOpenUrl 1st parameter problem, and your url problem, your program works.
-
April 15th, 2013, 01:52 AM
#17
Re: deployment catch 22
Originally Posted by Mike Pliam
Obviously, I'm missing something here - but what?
The sample I recommended starts with the following code:
Code:
BOOL GetFile (HINTERNET IN hOpen, // Handle from InternetOpen()
CHAR *szUrl, // Full URL
CHAR *szFileName) // Local file name
{
DWORD dwSize;
CHAR szHead[] = "Accept: */*\r\n\r\n";
VOID * szTemp[25];
HINTERNET hConnect;
FILE * pFile;
if ( !(hConnect = InternetOpenUrl ( hOpen, szUrl, szHead,
lstrlen (szHead), INTERNET_FLAG_DONT_CACHE, 0)))
{
cerr << "Error !" << endl;
return 0;
}
. . .
How this hint could be more explicit?
Last edited by Igor Vartanov; April 15th, 2013 at 01:55 AM.
Best regards,
Igor
-
April 15th, 2013, 12:07 PM
#18
Re: deployment catch 22
Do you ever get the feeling that you're wandering in circles?
Even though I finally got InternetOpen and InternetOpenUrl to work to download and read the update file from the website, it will not work in the Program Files (x86) directory and indicates Debugging from there indicates the InternetOpen operation completed successfully but the _fopen attempt failed. LastError == 'Access us denied'. Now, if you run this directly from the Program Files (x86) environment as 'Administrator', it works just fine to download and read the file. So it appears that I'm right back where I started from -- 'Catch 22'.
Is there no way for a non-administrator user to check for updates ?
At this point, I've given up and simply grayed out the menu option if the user is a non-administrator. What a whimp!
Last edited by Mike Pliam; April 15th, 2013 at 12:22 PM.
mpliam
-
April 15th, 2013, 12:15 PM
#19
Re: deployment catch 22
Paul, I do try to use GetLastError whenever I encounter a runtime problem. But getting the error message out is never pleasant, a fact attested to by the many complaints voiced on the internet concerning the difficulties of using FormatErrorMessage.
Turns out that one can use the following to get the system error message much more easily using the little known _com_error class:
See:
Lookup and Display Win32/COM Error Strings With One Line of Code By Brian C Hart, 31 Dec 2005
http://www.codeproject.com/Articles/...trings-With-On
The _com_error class
Code:
_com_error::ErrorMessage();
However, the returned message with both methods often as not returns 'Unknown error' or the like and one is forced to look the error number returned by GetLastError up on the web. A minor but annoying inconvenience.
mpliam
-
April 15th, 2013, 12:47 PM
#20
Re: deployment catch 22
Originally Posted by Mike Pliam
Do you ever get the feeling that you're wandering in circles?
Even though I finally got InternetOpen and InternetOpenUrl to work to download and read the update file from the website, it will not work in the Program Files (x86) directory
Mike, you definitely are going in circle. It's not a problem to read from internet being running in Program Files (x86) directory, but it's a problem to write somewhere under it. Just stop trying to write there, and you're fine. Read your version info to memory, parse it there in memory and ultimately download your binary to %TEMP% folder or elsewhere under user profile. Did it ever occurred to you that you're not obliged to write it next to your exe? And you always can make the path for writing to point wherever you want to?
Last edited by Igor Vartanov; April 15th, 2013 at 01:02 PM.
Best regards,
Igor
-
April 15th, 2013, 06:28 PM
#21
Re: deployment catch 22
Thanks for that idea, Igor. It occurred to me also, but I was unable to get the text from memory -- the void * szTemp buffer made it quite difficult for me and my attempts to trace it returned gibberish. It appears that the sample code downloads the server file in 'chunks', so how to read it into and out of memory without writing it to disk.
Code:
void CUeberKryptDlg::OnCheckForUpdates()
{
TRACE0("CUeberKryptDlg::OnCheckForUpdates:\n");
HINTERNET hOpen = NULL; // Handle from InternetOpen()
WCHAR *szUrl = _T("http://www.pliatech.com/ueberkrypt/ueberkryptupdate.inf"); // Full URL
WCHAR *szFileName = _T("ueberkryptupdate.inf"); // Local file name
hOpen = InternetOpen(_T("my agent"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_OPEN_TYPE_PRECONFIG);
DWORD dwError = GetLastError();
TRACE0("Last Error Message: "); OutputDebugString(_com_error(GetLastError()).ErrorMessage()); TRACE0("\n");
BOOL bRes = GetFile(hOpen, szUrl, szFileName);
if(!bRes) return;
BOOL CUeberKryptDlg::GetFile (HINTERNET hOpen, WCHAR *szUrl, WCHAR *szFileName)
{
DWORD dwSize;
WCHAR szHead[] = _T("Accept: */*\r\n\r\n");
VOID * szTemp[1024];
HINTERNET hConnect;
FILE * pFile;
memset(szTemp, 0x00, 1024);
if ( !(hConnect = InternetOpenUrl ( hOpen, szUrl, szHead,
lstrlen (szHead), INTERNET_FLAG_DONT_CACHE, 0)))
{
_RPT0(0, "InternetOpenUrl Error !\n");
DWORD dwError = GetLastError();
_RPT1(0, "dwError = %d\n", dwError);
_RPT0(0, "Last Error Message: "); OutputDebugString(_com_error(GetLastError()).ErrorMessage()); _RPT0(0, "\n");
return 0;
}
if ( !(pFile = _wfopen (szFileName, _T("wb") ) ) )
{
_RPT0(0, "_wfopen Error !\n");
DWORD dwError = GetLastError();
_RPT1(0, "dwError = %d\n", dwError);
_RPT0(0, "Last Error Message: "); OutputDebugString(_com_error(GetLastError()).ErrorMessage()); _RPT0(0, "\n");
return FALSE;
}
do
{
// Keep coping in 25 bytes chunks, while file has any data left.
// Note: bigger buffer will greatly improve performance.
if (!InternetReadFile (hConnect, szTemp, 50, &dwSize) )
{
fclose (pFile);
_RPT0(0, "InternetReadFile Error !\n");
return FALSE;
}
if (!dwSize)
break; // Condition of dwSize=0 indicate EOF. Stop.
else
{
//fwrite(szTemp, sizeof (char), dwSize , pFile);
OutputDebugString((wchar_t*)szTemp); // returns gibberish
//TRACE1("%s", (char*)szTemp);
}
} while (TRUE); // do
fflush (pFile);
fclose (pFile);
return TRUE;
}
mpliam
-
April 15th, 2013, 06:44 PM
#22
Re: deployment catch 22
This is wrong:
Code:
memset(szTemp, 0x00, 1024);
The last parameter denotes the number of bytes to set, not the number of VOID*'s.
Code:
memset(szTemp, 0x00, 1024 * sizeof(VOID*));
But given this, it's still wrong from the outset.
Reading the documentation to InternetReadFile states that you need a buffer that will receive the data. Just because the prototype shows LPVOID doesn't mean you declare a VOID pointer and pass it to the function. The pointer has to point somewhere, and your example doesn't do this.
Code:
BYTE szTemp[1024];
//...
if (!InternetReadFile (hConnect, (LPVOID)szTemp, 50, &dwSize) )
Regards,
Paul McKenzie
-
April 16th, 2013, 09:36 AM
#23
Re: deployment catch 22
Originally Posted by Mike Pliam
Thanks for that idea, Igor. It occurred to me also, but I was unable to get the text from memory
Consider the sample below. Please do not hesitate to ask questions.
Code:
#include <Windows.h>
#include <WinInet.h>
#pragma comment (lib, "WinInet.lib")
#include <string>
#include <iostream>
using namespace std;
#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
BOOL GetFile (HINTERNET IN hOpen, CHAR *szUrl, CHAR *szFileName);
int main(int argc, CHAR* argv[])
{
BOOL bResult = FALSE;
HINTERNET IN hOpen = InternetOpen("",
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
NULL,
NULL,
0 );
CHAR *szUrl = "http://www.pliatech.com/UeberKrypt";
CHAR *szFileName = "ueberkryptupdate.inf";
bResult = GetFile (hOpen, szUrl, szFileName);
InternetCloseHandle( hOpen );
return 0;
}
BOOL GetFile (HINTERNET IN hOpen, // Handle from InternetOpen()
CHAR *szUrl, // Full URL
CHAR *szFileName) // Local file name
{
DWORD dwSize;
LPSTR szHead = "Accept: */*\r\n\r\n";
CHAR szTemp[25];
HINTERNET hConnect = NULL;
FILE * pFile;
LPSTR pContent = NULL;
DWORD dwLen = 0;
string url = szUrl;
url += "/";
url += szFileName;
if ( !(hConnect = InternetOpenUrl ( hOpen, url.c_str(), szHead,
lstrlen (szHead), INTERNET_FLAG_DONT_CACHE, 0)))
{
cerr << "hConnect Error !" << endl;
return 0;
}
// get http status code
DWORD dwQueryBufLen = sizeof( szTemp );
if( ::HttpQueryInfo( hConnect, HTTP_QUERY_STATUS_CODE, &szTemp, &dwQueryBufLen, NULL ) )
{
DWORD dwCode = 0;
sscanf( szTemp, "%d", &dwCode );
if( 200 > dwCode || dwCode > 299 )
return FALSE;
}
// get file length from http headers
dwQueryBufLen = sizeof( szTemp );
if( ::HttpQueryInfo( hConnect, HTTP_QUERY_CONTENT_LENGTH, szTemp, &dwQueryBufLen, NULL ) )
{
sscanf( szTemp, "%d", &dwLen );
pContent = (LPSTR)LocalAlloc(LPTR, dwLen + sizeof(TCHAR));
}
// read file in one chunk
if (!InternetReadFile (hConnect, pContent, dwLen, &dwSize) )
{
InternetCloseHandle(hConnect);
cerr << "InternetReadFile Error !" << endl;
return FALSE;
}
// cleanup
InternetCloseHandle(hConnect);
// do with your text buffer whatever you want
cout << pContent << endl;
LocalFree(pContent);
return TRUE;
}
Last edited by Igor Vartanov; April 16th, 2013 at 09:40 AM.
Best regards,
Igor
-
April 16th, 2013, 01:05 PM
#24
Re: deployment catch 22
Thanks, Igor. Yours is a far more sophisticated approach than mine and seems to work quite nicely. I removed the single break point in your code, but it still hangs when I attempt to run in debug config and use Start Debug. But if I just use Start Without Debugging or Release config, no such problem occurs. I cannot find any error messages or hidden breakpoints, so I am puzzled as to this behaviour as I have not seen this before. Also, using Start Without Debugging while running dbgview.exe, it runs fine and there are no error messages or memory leaks detectable. Can you explain this behaviour?
In addition, I have encountered considerable difficulty in converting your code to Unicode. Specifically, I cannot get meaningful text from LPWSTR pContent.
Code:
BOOL CUeberKryptDlg::GetFile (HINTERNET IN hOpen, // Handle from InternetOpen()
WCHAR *szUrl, // Full URL
WCHAR *szFileName) // Local file name
{
DWORD dwSize;
LPWSTR szHead = _T("Accept: */*\r\n\r\n");
WCHAR szTemp[25];
HINTERNET hConnect = NULL;
FILE * pFile;
LPWSTR pContent = NULL;
DWORD dwLen = 0;
wstring url = szUrl;
url += _T("/");
url += szFileName;
if ( !(hConnect = InternetOpenUrl ( hOpen, url.c_str(), szHead,
lstrlen (szHead), INTERNET_FLAG_DONT_CACHE, 0)))
{
TRACE0("hConnect Error !\n");
DWORD dwError = GetLastError();
TRACE1("dwError = %d\n", dwError);
TRACE0("Last Error: "); OutputDebugString(_com_error(GetLastError()).ErrorMessage()); TRACE0("\n");
return 0;
}
// get http status code
DWORD dwQueryBufLen = sizeof( szTemp );
if( ::HttpQueryInfo( hConnect, HTTP_QUERY_STATUS_CODE, &szTemp, &dwQueryBufLen, NULL ) )
{
DWORD dwCode = 0;
//sscanf( szTemp, "%d", &dwCode );
swscanf( szTemp, _T("%d"), &dwCode );
if( 200 > dwCode || dwCode > 299 )
return FALSE;
}
// get file length from http headers
dwQueryBufLen = sizeof( szTemp );
if( ::HttpQueryInfo( hConnect, HTTP_QUERY_CONTENT_LENGTH, szTemp, &dwQueryBufLen, NULL ) )
{
swscanf( szTemp, _T("%d"), &dwLen );
pContent = (LPWSTR)LocalAlloc(LPTR, dwLen + sizeof(TCHAR));
}
// read file in one chunk
if (!InternetReadFile (hConnect, pContent, dwLen, &dwSize) )
{
TRACE0("InternetReadFile Error !\n");
DWORD dwError = GetLastError();
TRACE1("dwError = %d\n", dwError);
TRACE0("Last Error: "); OutputDebugString(_com_error(GetLastError()).ErrorMessage()); TRACE0("\n");
InternetCloseHandle(hConnect);
return FALSE;
}
// cleanup
InternetCloseHandle(hConnect);
// do with your text buffer whatever you want
//cout << pContent << endl;
TRACE1("pContent = %s\n", pContent);
OutputDebugString(pContent); TRACE0("\n");
wstring ws = pContent;
TRACE0("pContent = : "); OutputDebugString(ws.c_str()); TRACE0("\n");
size_t n = 0;
n = ws.find(_T("Version="), 0);
wstring wss = ws.substr(n + 8, 3);
TRACE1("n = %d\n", n);
OutputDebugString(wss.c_str()); TRACE0("\n");
//cout << "Version = " << ss << endl;
float fUpdateVersion = _wtof((wchar_t*)wss.c_str());
TRACE1("Update Version = %0.2f\n", fUpdateVersion);
MessageBox(CString(wss.c_str()), _T(""), MB_ICONINFORMATION);
/*
[Update]
Version=2.3
Install=http://www.pliatech.com/ueberkrypt/UeberKryptInstaller.msi
Info=Uploaded February 25, 2013 by MBP.
File=http://www.pliatech.com/ueberkrypt/ueberkryptupdate.inf
*/
LocalFree(pContent);
return TRUE;
}
Last edited by Mike Pliam; April 16th, 2013 at 01:48 PM.
mpliam
-
April 16th, 2013, 01:45 PM
#25
Re: deployment catch 22
Have no idea. What I do to debug the program in VS2010:
Build with debug info:
Code:
cl 83.cpp /EHsc /Zi
Run the built exe in VS:
Then I'm able to go through the whole code with F10/F11/BreakPoint+F5. Not a single problem occurs.
Best regards,
Igor
-
April 16th, 2013, 01:54 PM
#26
Re: deployment catch 22
Thanks. I'll try that. Please note that I edited my last post regarding Unicode just as you posted your last comment.
When I use devenv ueberkrypt.exe from the VS command prompt, a new VS 2010 interface comes up containing the exe. When I use Start Debugging I get the same hang. I presume that I am using a build with debug capabilities because I'm not certain how to build the whole dialog-based app from the command prompt and it's already been built.
Last edited by Mike Pliam; April 16th, 2013 at 03:11 PM.
mpliam
-
April 16th, 2013, 02:17 PM
#27
Re: deployment catch 22
Originally Posted by Mike Pliam
In addition, I have encountered considerable difficulty in converting your code to Unicode. Specifically, I cannot get meaningful text from LPWSTR pContent.
I wonder how can you expect your downloaded file be of wide characters while it's in ANSI?
Version compilable to ANSI/Unicode:
Code:
#include <Windows.h>
#include <WinInet.h>
#include <tchar.h>
#pragma comment (lib, "WinInet.lib")
#include <string>
#include <iostream>
using namespace std;
#ifdef _UNICODE
#define tstring wstring
#define tcout wcout
#define tcerr wcerr
#else
#define tstring string
#define tcout cout
#define tcerr cerr
#endif
#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
BOOL GetFile (HINTERNET IN hOpen, TCHAR *szUrl, TCHAR *szFileName);
int _tmain(int argc, TCHAR* argv[])
{
BOOL bResult = FALSE;
HINTERNET IN hOpen = InternetOpen(_T(""),
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
NULL,
NULL,
0 );
TCHAR *szUrl = _T("http://www.pliatech.com/UeberKrypt");
TCHAR *szFileName = _T("ueberkryptupdate.inf");
bResult = GetFile (hOpen, szUrl, szFileName);
InternetCloseHandle( hOpen );
return 0;
}
BOOL GetFile (HINTERNET IN hOpen, // Handle from InternetOpen()
TCHAR *szUrl, // Full URL
TCHAR *szFileName) // Local file name
{
DWORD dwSize;
LPCTSTR szHead = _T("Accept: */*\r\n\r\n");
TCHAR szTemp[25];
HINTERNET hConnect = NULL;
FILE * pFile;
LPSTR pContent = NULL;
DWORD dwLen = 0;
tstring url = szUrl;
url += _T("/");
url += szFileName;
if ( !(hConnect = InternetOpenUrl ( hOpen, url.c_str(), szHead,
_tcslen (szHead), INTERNET_FLAG_DONT_CACHE, 0)))
{
tcerr << _T("hConnect Error !") << endl;
return 0;
}
// get http status code
DWORD dwQueryBufLen = sizeof( szTemp );
if( ::HttpQueryInfo( hConnect, HTTP_QUERY_STATUS_CODE, &szTemp, &dwQueryBufLen, NULL ) )
{
DWORD dwCode = 0;
_stscanf( szTemp, _T("%d"), &dwCode );
if( 200 > dwCode || dwCode > 299 )
return FALSE;
}
// get file length from http headers
dwQueryBufLen = sizeof( szTemp );
if( ::HttpQueryInfo( hConnect, HTTP_QUERY_CONTENT_LENGTH, szTemp, &dwQueryBufLen, NULL ) )
{
_stscanf( szTemp, _T("%d"), &dwLen );
pContent = (LPSTR)LocalAlloc(LPTR, dwLen + sizeof(TCHAR));
}
// read file in one chunk
if (!InternetReadFile (hConnect, pContent, dwLen, &dwSize) )
{
InternetCloseHandle(hConnect);
tcerr << _T("InternetReadFile Error !") << endl;
return FALSE;
}
// cleanup
InternetCloseHandle(hConnect);
// do with your text buffer whatever you want
cout << pContent << endl;
LocalFree(pContent);
return TRUE;
}
Code:
cl 83.cpp /EHsc /Zi /D"UNICODE" /D"_UNICODE"
Best regards,
Igor
-
April 16th, 2013, 07:38 PM
#28
Re: deployment catch 22
I wonder how can you expect your downloaded file be of wide characters while it's in ANSI?
Stupid of me, of course!!
Thank you once again. This works:
Code:
size_t nchars = 0;
wchar_t wbuf[1024];
memset(wbuf, 0x00, 1024 * sizeof(wchar_t));
errno_t ent = mbstowcs_s(&nchars, wbuf, pContent, 1024);
TRACE0("wbuf =: "); OutputDebugString(wbuf); TRACE0("\n");
MessageBox(wbuf, _T(""), MB_ICONINFORMATION);
mpliam
-
April 16th, 2013, 11:26 PM
#29
Re: deployment catch 22
This works either. And much safer, I dare say.
Code:
CString content(pContent);
tcout << content.GetString() << endl;
Best regards,
Igor
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|