0

I have one win32 prog where i want to call GetOpenFileName() but every time it got crash and CommDlgExtendedError() return error code as 1008. Please help me out.

char Filestring[MAX_PATH] = "\0";
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFile = (LPWSTR)Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileName(&ofn) == TRUE)
{

}

else
{
    int err = CommDlgExtendedError();
}
prod
  • 1
  • 5
    `(LPWSTR)Filestring` - Every cast is a lie. This one, too. It's an out-of-bounds array access waiting to happen, and a debug build (using the debug heap) just makes sure this will happen. If you want to make the immediate problem go away, use `wchar_t Filestring[MAX_PATH]` instead. If you wish to solve the problem, be explicit about using the Unicode API (e.g. `OPENFILENAMEW`, `GetOpenFileNameW`, etc. – IInspectable Jun 21 '22 at 12:41
  • Adding to my question in "Disassembly" it is showing as it is trying to access 0th memory location. Means, the null pointer but i did not find any , i have checked by debugging there is no null pointer. Since, i am new in this field, i apologize if any mistake is there. – prod Jun 21 '22 at 12:48
  • Unrelated: Never check against TRUE, check for FALSE. – Anders Jun 21 '22 at 13:03
  • As already mentioned, you can't simply cast a `char*` string to `wchar_t*` and expect it to work. If you want to use the wide-char interface, declare your buffer as such: `wchar_t Filestring[MAX_PATH] = L"\0";`. – Adrian Mole Jun 21 '22 at 14:37
  • 1
    Key takeaway message is not to cast in the way you did here. Presumably you added the cast because the compiler reported a type mismatch. The cast does not change the fact that the types don't match, it just tells the compiler to ignore the error, and trust that you know better. Invariably the compiler knows better. – David Heffernan Jun 21 '22 at 14:52
  • @AdrianMole Thank you for your solution. Here "lpstrFile" is LPWSTR type which is typedef of "wchar_t*". So, I can not use wchar_t. If it is possible please put some light here. – prod Jun 22 '22 at 07:45
  • "*Here `lpstrFile` is `LPWSTR` type which is typedef of `wchar_t*`. So, I can not use `wchar_t`*" - the fact that you just said that shows you need to brush up on the fundamentals of the C++ language. Get a [good C++ book](https://stackoverflow.com/questions/388242/) and strengthen your basics before you tackle the Win32 API. – Remy Lebeau Jun 22 '22 at 07:52
  • @Remy Lebeau Noted with thanks. I will. – prod Jun 22 '22 at 09:56

1 Answers1

0

You are using the TCHAR version of the GetOpenFileName() API, which maps to either the ANSI (GetOpenFileNameA()) or Unicode (GetOpenFileNameW()) API depending on whether UNICODE is defined.

Since ofn.lpstrFile is accepting a LPWSTR (wchar_t*) pointer, expecting it to point at a wchar[] buffer, your project clearly has UNICODE defined. But you are giving it a type-casted pointer to a char[] buffer instead, which has 1/2 the storage space than you are telling the API is available for it to write to.

Your type-cast on the ofn.lpstrFile field is lying to the API. The code is calling the Unicode API, so it will write Unicode data to your char[] buffer, giving you mojibake output, and risking a buffer overflow.

You should use a TCHAR[] buffer instead to match what the API is expecting, eg:

TCHAR Filestring[MAX_PATH] = TEXT("\0");
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileName(&ofn))
{
    ...
}
else
{
    int err = CommDlgExtendedError();
    ...
}

Otherwise, use the ANSI or Unicode API explicitly, depending on your desired character encoding, eg:

CHAR Filestring[MAX_PATH] = "\0";
OPENFILENAMEA ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileNameA(&ofn))
{
    ...
}
else
{
    int err = CommDlgExtendedError();
    ...
}
WCHAR Filestring[MAX_PATH] = L"\0";
OPENFILENAMEW ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileNameW(&ofn))
{
    ...
}
else
{
    int err = CommDlgExtendedError();
    ...
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you for your answer. I tried everything but getting the same error. When i called it from "InitInstance" it is working fine. But getting error if i called it from "WndProc". – prod Jun 22 '22 at 05:01
  • You're creating a popup dialog in `WndProc`? So, in response to a particular message? That's not how to do things. – Adrian Mole Jun 22 '22 at 07:54
  • @prod 1008 is not a typical error code that `CommDlgExtendedError()` would return. After making the suggested changes, if you are still getting an error then please edit your question to provide a [mcve] that reproduces the error. – Remy Lebeau Jun 22 '22 at 07:57
  • @AdrianMole Thank you for your patience. I will restructure my code. – prod Jun 22 '22 at 10:15
  • @Remy Lebeau Thank you for your patience. I will restructure my code. – prod Jun 22 '22 at 10:15