1

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!

Mike D
  • 2,753
  • 8
  • 44
  • 77
  • 3
    That is not useful without symbols. – Raymond Chen Apr 02 '13 at 17:10
  • If you're using Visual Studio, you should be able to get symbols by right-clicking on the stack and choosing "Load Symbols from Microsoft Symbol Servers". – Adrian McCarthy Apr 02 '13 at 18:21
  • 1
    I would very carefully check the OPENFILENAME struct you pass in. In particular, the fields related to the filter, as the filter can be remembered by the function and re-used in the future. – Adrian McCarthy Apr 02 '13 at 18:23
  • Filter set as follows char filter[32]="Text Files\0*.TXT;\0\0"; – Mike D Apr 02 '13 at 19:16
  • Hey, you deleted the stack trace. Please include the stack trace with symbols. – Raymond Chen Apr 02 '13 at 20:50
  • I added the stack BUT I am unable to get symbols probably because I have an old Visual c++. – Mike D Apr 03 '13 at 00:45
  • It appears to me that the problem occurs when the GOFN stuff is about to open the popup as the mouse cursor hovers above a file name. – Mike D Apr 03 '13 at 11:27
  • The free downloadable [debugger tools package](http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx) can get symbols from the symbol server. Without symbols there is nothing meaningful in the trace. – Raymond Chen Apr 03 '13 at 14:18
  • I ran your program and followed the instructions (select file on desktop, hover over a file with a long name) and got no crash. I suspect some third party shell extension is the problem. – Raymond Chen Apr 03 '13 at 15:43

1 Answers1

3

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.

Roger Rowland
  • 25,885
  • 11
  • 72
  • 113
  • Even if this turns out not to be *the* answer to the question, this will be valuable circumstantial knowledge. +1 – 0xC0000022L Apr 03 '13 at 12:29
  • I hope so, and it was too unwieldy to post as a comment. – Roger Rowland Apr 03 '13 at 12:45
  • I don't have CoInitializeEX but do have CoInitialize. I found various articles suggesting the use of #define _WIN32_DCOM but that does define CoInitializeEx for me. I tried adding CoInitialize but the problem persists. Thanks for the answer, at least I know the problem isn't of my making. :-) – Mike D Apr 03 '13 at 14:28
  • Ok, thanks for accepting - `CoInitialize()` is fine, it's just deprecated in later SDK's but it does the same thing. You have to call it in the same thread that calls `GetOpenFileName()` (in case you didn't). – Roger Rowland Apr 03 '13 at 15:18
  • I did call it from the new thread and I checked that it returned S_OK. No joy. – Mike D Apr 03 '13 at 17:20
  • Related: http://jackiichan.wordpress.com/2007/09/19/getopenfilename-and-some-deep-crashes/ – Adrian McCarthy Dec 12 '13 at 23:20