deployment catch 22 - Page 2
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 29 of 29

Thread: deployment catch 22

  1. #16
    Join Date
    May 2002
    Location
    Lindenhurst, NY
    Posts
    867

    Re: deployment catch 22

    One more hint: After correcting your InternetOpenUrl 1st parameter problem, and your url problem, your program works.

  2. #17
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,977

    Re: deployment catch 22

    Quote Originally Posted by Mike Pliam View Post
    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

  3. #18
    Join Date
    May 2002
    Posts
    1,723

    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

  4. #19
    Join Date
    May 2002
    Posts
    1,723

    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

  5. #20
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,977

    Re: deployment catch 22

    Quote Originally Posted by Mike Pliam View Post
    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

  6. #21
    Join Date
    May 2002
    Posts
    1,723

    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

  7. #22
    Join Date
    Apr 1999
    Posts
    27,427

    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

  8. #23
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,977

    Re: deployment catch 22

    Quote Originally Posted by Mike Pliam View Post
    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

  9. #24
    Join Date
    May 2002
    Posts
    1,723

    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

  10. #25
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,977

    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:
    Code:
    devenv 83.exe
    Then I'm able to go through the whole code with F10/F11/BreakPoint+F5. Not a single problem occurs.
    Best regards,
    Igor

  11. #26
    Join Date
    May 2002
    Posts
    1,723

    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

  12. #27
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,977

    Re: deployment catch 22

    Quote Originally Posted by Mike Pliam View Post
    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

  13. #28
    Join Date
    May 2002
    Posts
    1,723

    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

  14. #29
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,977

    Re: deployment catch 22

    This works either. And much safer, I dare say.
    Code:
        CString content(pContent);
        tcout << content.GetString() << endl;
    Best regards,
    Igor

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center