Question

GetOpenFileName fails with access violation. File must be on DESKTOP and have long name. Problem occurs only after first successful open of the file. Problem occurs when mouse cursor hovers over file as tool tip about to be displayed.

See the answer below. I'm leaving the original problem description below.

Mike D.

=======================

I'm using GetOpenFileName. I sometimes get a access violation deep inside shell32. The violation never occurs the first time this code is used, it often takes five or six tries. Also it appears that if one selects a file in second or two after the open file window pops up, the violation does not occur. Also, the call stack displayed when I debug this does not include any of my code. It's as if some independent thread is waking up to do something.

Any insights into how I might debug this greatly appreciated!

I made a "hello" world app exhibiting the same behavior. It, however, requires many more tries before it fails. It also seems that one has to switch directories before it will fail.

The GOFN is done from a thread created just for that purpose. Below is the code from the "hello world" app.

typedef struct 
{
public:
    HWND        hWnd;
    HINSTANCE   hInst;
} def_params, *p_params;

DWORD WINAPI ReadLogFile_DataRecorderThread (PVOID pvoid);

void ReadLogFile_DataRecorder (HWND hWnd, HINSTANCE hInst)  // ***************************
{
    static def_params Params;

    Params.hWnd = hWnd;
    Params.hInst = hInst;

    HANDLE T = CreateThread (NULL,0,ReadLogFile_DataRecorderThread,&Params,0,NULL);

    CloseHandle (T);

    return;
}

DWORD WINAPI ReadLogFile_DataRecorderThread (PVOID pvoid)   
{
    p_params P = (p_params) pvoid;

    HWND hWnd = P->hWnd;
    HINSTANCE hInst = P->hInst;

    char    ReadLogFileLastDir[256];

//  static def_OpenFileHook Hook;

    OPENFILENAME    ofn;
    char            fn[MAX_PATH]="\0";
    char            filter[32]="Text Files\0*.TXT;\0\0";
    char            title[]="Open IMC Data Recorder Log File";
    char            defext[]="TXT";
    int             status;

// Get File Name

    fn[0] = '\0';
    ReadLogFileLastDir[0] = '\0';

    ZeroMemory(&ofn, sizeof(ofn));

    ofn.lStructSize         = sizeof(ofn);
    ofn.hwndOwner           = hWnd;
    ofn.hInstance           = hInst;
    ofn.hInstance           = (HINSTANCE) GetWindowLong (hWnd, GWL_HINSTANCE);

    ofn.lpstrFilter         = filter;
    ofn.nFilterIndex        = 0;
    ofn.lpstrCustomFilter   = NULL ;
    ofn.nMaxCustFilter      = 0 ;
    ofn.lpstrFile           = fn;
    ofn.nMaxFile            = sizeof(fn);
    ofn.lpstrFileTitle      = NULL;

    if (ReadLogFileLastDir[0] == '\0')
    {
        SHGetSpecialFolderPath (NULL,ReadLogFileLastDir,0x0005,false);
    };
    ofn.lpstrInitialDir = ReadLogFileLastDir;
    ofn.lpstrTitle          = title;
    ofn.Flags               = OFN_FILEMUSTEXIST  | 
                              OFN_PATHMUSTEXIST  | 
                              OFN_EXPLORER       | 
                              // OFN_ENABLETEMPLATE | 
                              OFN_ENABLESIZING   | 
                              // OFN_ENABLEHOOK     |
                              OFN_READONLY;
    ofn.lpstrDefExt         = NULL;
    ofn.lpfnHook            = NULL;         // Hook.DialogHook; // hook routine
    ofn.lCustData           = NULL;          // (long) &Hook;       // data for hook routine
    ofn.lpTemplateName      = NULL;          // MAKEINTRESOURCE(IDD_HOOKFILEOPEN);
    ofn.nFileOffset         = 0 ;
    ofn.nFileExtension      = 0 ;
    ofn.lpstrDefExt         = defext;

    status = GetOpenFileName (&ofn);

    int S;

    S = CommDlgExtendedError();

    return 0;
}

When it fails, the call stack looks like this...

SHELL32! 7ca4e035()
SHELL32! 7cb2dc16()
SHELL32! 7cb2dd5a()
SHELL32! 7cb27361()
SHELL32! 7c9f40a3()
BROWSEUI! 75f81b9a()
SHLWAPI! 77f69548()
NTDLL! 7c927545()
NTDLL! 7c927583()
NTDLL! 7c927645()
NTDLL! 7c92761c()
KERNEL32! 7c80b50b()

Sorry but I am unable to get symbols for these as I have an old Visual C++ :-(

It appears to me that the problem occurs when the GOFN stuff is about to open the popup describing the file as the mouse cursor hovers over the file name.

The set of circumstances causing the problem are somewhat weird. Experiments show one has to do the following in the GOFN window:

  • Open a file on the DESKTOP
  • Hover over a long file name

If I do this twice, it always fails. The file name I used was

IMCLOG_20120323_1658_-_20120324_0653_CST_+DST_E2_2_second.TXT

I tried the same thing with NOTEPAD and the same problem occurs!

Was it helpful?

Solution

I found numerous reports of the same problem. For example:

Social.MSDN Problem report
CodeProject question
CodeGuru thread

There was also a Google cached link to a since-deleted MS Connect bug report. As you discovered, the problem seems to be particular to files in the Desktop.

The only suggested solution I found is to call CoInitializeEx(NULL) at the start of the thread, and call CoUninitialize() at the end, so that's worth trying.

Also, the MSDN documentation for GetOpenFileName() says:

Starting with Windows Vista, the Open and Save As common dialog boxes have been superseded by the Common Item Dialog.

So it may be worth discarding GetOpenFileName() completely.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top