Compare commits

...

3 Commits

Author SHA1 Message Date
Timo Kreuzer a6b08dac68
Merge d8ff65110b into dcf9eb060a 2024-04-27 02:44:03 +02:00
Marcin Jabłoński dcf9eb060a
[SHELL32] Fix Control_RunDLLW (#5400)
This commit makes Control_RunDLLW pass all but one tests from rostests (the one test that fails is the first one, but it only fails if the path to the test program contains a space).

- Rework string parsing in the Control_DoLaunch routine
- Do not send the CPL_STARTWPARMSW message, if no extra parameters were specified (fixes the failing Got NULL lParam2! and some CPL_STARTWPARMSW: expected -1 got %d tests)
- Do not resolve invalid dialog names to index zero, unless the name is empty (fixes some of the failing CPL_DBLCLK: expected -1 got %d tests)
- Handle quotes in the second part of wszCmd

CORE-8981
2024-04-26 18:28:46 -06:00
Timo Kreuzer d8ff65110b [NTOS:IO] Fix broken pool allocations
ExAllocatePoolWithTag doesn't raise an exception on failure, only ExAllocatePoolWithQuotaTag does. Use that when quotas are relevant instead of silently continuing with a NULL pointer.
2024-04-22 14:56:07 +03:00
3 changed files with 217 additions and 95 deletions

View File

@ -873,6 +873,7 @@ static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
* "a path\foo.cpl"
*/
{
#ifndef __REACTOS__
LPWSTR buffer;
LPWSTR beg = NULL;
LPWSTR end;
@ -952,14 +953,6 @@ static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
applet = Control_LoadApplet(hWnd, buffer, panel);
if (applet)
{
#ifdef __REACTOS__
ULONG_PTR cookie;
BOOL bActivated;
ATOM aCPLName;
ATOM aCPLFlags;
ATOM aCPLPath;
AppDlgFindData findData;
#endif
/* we've been given a textual parameter (or none at all) */
if (sp == -1) {
while ((++sp) != applet->count) {
@ -975,65 +968,201 @@ static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
sp = 0;
}
#ifdef __REACTOS__
bActivated = (applet->hActCtx != INVALID_HANDLE_VALUE ? ActivateActCtx(applet->hActCtx, &cookie) : FALSE);
aCPLPath = GlobalFindAtomW(applet->cmd);
if (!aCPLPath)
{
aCPLPath = GlobalAddAtomW(applet->cmd);
}
aCPLName = GlobalFindAtomW(L"CPLName");
if (!aCPLName)
{
aCPLName = GlobalAddAtomW(L"CPLName");
}
aCPLFlags = GlobalFindAtomW(L"CPLFlags");
if (!aCPLFlags)
{
aCPLFlags = GlobalAddAtomW(L"CPLFlags");
}
findData.szAppFile = applet->cmd;
findData.sAppletNo = (UINT_PTR)(sp + 1);
findData.aCPLName = aCPLName;
findData.aCPLFlags = aCPLFlags;
findData.hRunDLL = applet->hWnd;
findData.hDlgResult = NULL;
// Find the dialog of this applet in the first instance.
// Note: The simpler functions "FindWindow" or "FindWindowEx" does not find this type of dialogs.
EnumWindows(Control_EnumWinProc, (LPARAM)&findData);
if (findData.hDlgResult)
{
BringWindowToTop(findData.hDlgResult);
}
else
{
SetPropW(applet->hWnd, (LPTSTR)MAKEINTATOM(aCPLName), (HANDLE)MAKEINTATOM(aCPLPath));
SetPropW(applet->hWnd, (LPTSTR)MAKEINTATOM(aCPLFlags), UlongToHandle(sp + 1));
Control_ShowAppletInTaskbar(applet, sp);
#endif
if (!applet->proc(applet->hWnd, CPL_STARTWPARMSW, sp, (LPARAM)extraPmts))
applet->proc(applet->hWnd, CPL_DBLCLK, sp, applet->info[sp].data);
#ifdef __REACTOS__
RemovePropW(applet->hWnd, applet->cmd);
GlobalDeleteAtom(aCPLPath);
}
#endif
Control_UnloadApplet(applet);
#ifdef __REACTOS__
if (bActivated)
DeactivateActCtx(0, cookie);
#endif
}
HeapFree(GetProcessHeap(), 0, buffer);
#else
LPWSTR buffer;
LPWSTR ptr;
signed sp = -1;
LPCWSTR extraPmts = L"";
BOOL quoted = FALSE;
CPlApplet *applet;
LPCWSTR pchFirstComma = NULL, pchSecondComma = NULL;
LPCWSTR pchLastUnquotedSpace = NULL;
LPWSTR wszDialogBoxName;
int i = 0;
SIZE_T nLen = lstrlenW(wszCmd);
buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*buffer) * (nLen + 1));
wszDialogBoxName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wszDialogBoxName) * (nLen + 1));
if (wszDialogBoxName == NULL || buffer == NULL)
{
if (buffer != NULL)
HeapFree(GetProcessHeap(), 0, buffer);
if (wszDialogBoxName != NULL)
HeapFree(GetProcessHeap(), 0, wszDialogBoxName);
return;
}
/* Search for unquoted commas and spaces. */
for (i = 0; i < nLen; i++)
{
if (quoted && wszCmd[i] != L'"')
continue;
switch (wszCmd[i])
{
case L'"':
quoted = !quoted;
break;
case L',':
if (!pchFirstComma)
pchFirstComma = &wszCmd[i];
else if (!pchSecondComma)
pchSecondComma = &wszCmd[i];
break;
case L' ':
pchLastUnquotedSpace = &wszCmd[i];
break;
}
}
/* If no unquoted commas are found, parameters are either space separated, or the entire string
* is a CPL path. */
if (!pchFirstComma)
{
/* An unquoted space was found in the string. Assume the last word is the dialog box
* name/number. */
if (pchLastUnquotedSpace)
{
int nSpaces = 0;
while (pchLastUnquotedSpace[nSpaces] == L' ')
nSpaces++;
StringCchCopyNW(buffer, nLen + 1, wszCmd, pchLastUnquotedSpace - wszCmd);
StringCchCopyW(wszDialogBoxName, nLen + 1, pchLastUnquotedSpace + nSpaces);
}
/* No parameters were passed, the entire string is the CPL path. */
else
{
StringCchCopyW(buffer, nLen + 1, wszCmd);
}
}
/* If an unquoted comma was found, there are at least two parts of the string:
* - the CPL path
* - either a dialog box number preceeded by @, or a dialog box name.
* If there was a second unqoted comma, there is another part of the string:
* - the rest of the parameters. */
else
{
/* If there was no second unquoted comma in the string, the CPL path ends at thes
* null terminator. */
if (!pchSecondComma)
pchSecondComma = wszCmd + nLen;
StringCchCopyNW(buffer, nLen + 1, wszCmd, pchFirstComma - wszCmd);
StringCchCopyNW(wszDialogBoxName,
nLen + 1,
pchFirstComma + 1,
pchSecondComma - pchFirstComma - 1);
if (pchSecondComma != wszCmd + nLen)
{
extraPmts = pchSecondComma + 1;
}
}
/* Remove the quotes from both buffers. */
while ((ptr = StrChrW(buffer, '"')))
memmove(ptr, ptr+1, lstrlenW(ptr)*sizeof(WCHAR));
while ((ptr = StrChrW(wszDialogBoxName, '"')))
memmove(ptr, ptr+1, lstrlenW(ptr)*sizeof(WCHAR));
if (wszDialogBoxName[0] == L'@')
{
sp = _wtoi(wszDialogBoxName + 1);
}
TRACE("cmd %s, extra %s, sp %d\n", debugstr_w(buffer), debugstr_w(extraPmts), sp);
applet = Control_LoadApplet(hWnd, buffer, panel);
if (applet)
{
ULONG_PTR cookie;
BOOL bActivated;
ATOM aCPLName;
ATOM aCPLFlags;
ATOM aCPLPath;
AppDlgFindData findData;
/* we've been given a textual parameter (or none at all) */
if (sp == -1)
{
while ((++sp) != applet->count)
{
TRACE("sp %d, name %s\n", sp, debugstr_w(applet->info[sp].name));
if (StrCmpIW(wszDialogBoxName, applet->info[sp].name) == 0)
break;
}
}
if (sp >= applet->count && wszDialogBoxName[0] == L'\0')
{
sp = 0;
}
bActivated = (applet->hActCtx != INVALID_HANDLE_VALUE ? ActivateActCtx(applet->hActCtx, &cookie) : FALSE);
if (sp < applet->count)
{
aCPLPath = GlobalFindAtomW(applet->cmd);
if (!aCPLPath)
aCPLPath = GlobalAddAtomW(applet->cmd);
aCPLName = GlobalFindAtomW(L"CPLName");
if (!aCPLName)
aCPLName = GlobalAddAtomW(L"CPLName");
aCPLFlags = GlobalFindAtomW(L"CPLFlags");
if (!aCPLFlags)
aCPLFlags = GlobalAddAtomW(L"CPLFlags");
findData.szAppFile = applet->cmd;
findData.sAppletNo = (UINT_PTR)(sp + 1);
findData.aCPLName = aCPLName;
findData.aCPLFlags = aCPLFlags;
findData.hRunDLL = applet->hWnd;
findData.hDlgResult = NULL;
// Find the dialog of this applet in the first instance.
// Note: The simpler functions "FindWindow" or "FindWindowEx" does not find this type of dialogs.
EnumWindows(Control_EnumWinProc, (LPARAM)&findData);
if (findData.hDlgResult)
{
BringWindowToTop(findData.hDlgResult);
}
else
{
SetPropW(applet->hWnd, (LPTSTR)MAKEINTATOM(aCPLName), (HANDLE)MAKEINTATOM(aCPLPath));
SetPropW(applet->hWnd, (LPTSTR)MAKEINTATOM(aCPLFlags), UlongToHandle(sp + 1));
Control_ShowAppletInTaskbar(applet, sp);
if (extraPmts[0] == L'\0' ||
!applet->proc(applet->hWnd, CPL_STARTWPARMSW, sp, (LPARAM)extraPmts))
{
applet->proc(applet->hWnd, CPL_DBLCLK, sp, applet->info[sp].data);
}
RemovePropW(applet->hWnd, applet->cmd);
GlobalDeleteAtom(aCPLPath);
}
}
Control_UnloadApplet(applet);
if (bActivated)
DeactivateActCtx(0, cookie);
}
HeapFree(GetProcessHeap(), 0, buffer);
HeapFree(GetProcessHeap(), 0, wszDialogBoxName);
#endif
}
/*************************************************************************

View File

@ -2467,7 +2467,7 @@ FinishDlgProc(HWND hwndDlg,
if (!SetupData->UnattendSetup || !SetupData->DisableGeckoInst)
{
/* Run the Wine Gecko prompt */
Control_RunDLLW(hwndDlg, 0, L"appwiz.cpl install_gecko", SW_SHOW);
Control_RunDLLW(hwndDlg, 0, L"appwiz.cpl,,install_gecko", SW_SHOW);
}
/* Set title font */

View File

@ -2176,19 +2176,23 @@ NtQueryDirectoryFile(IN HANDLE FileHandle,
/* Check if this is buffered I/O */
if (DeviceObject->Flags & DO_BUFFERED_IO)
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
if (!Irp->AssociatedIrp.SystemBuffer)
/* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
_SEH2_TRY
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Allocating failed, clean up and return the exception code */
IopCleanupAfterException(FileObject, Irp, Event, NULL);
if (AuxBuffer) ExFreePoolWithTag(AuxBuffer, TAG_SYSB);
/* Return the exception code */
return STATUS_INSUFFICIENT_RESOURCES;
return _SEH2_GetExceptionCode();
}
_SEH2_END;
/* Set the buffer and flags */
Irp->UserBuffer = FileInformation;
@ -2508,14 +2512,12 @@ NtQueryInformationFile(IN HANDLE FileHandle,
StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
StackPtr->FileObject = FileObject;
/* Enter SEH */
/* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
_SEH2_TRY
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -2978,14 +2980,12 @@ NtReadFile(IN HANDLE FileHandle,
/* Check if we have a buffer length */
if (Length)
{
/* Enter SEH */
/* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
_SEH2_TRY
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -3281,14 +3281,12 @@ NtSetInformationFile(IN HANDLE FileHandle,
StackPtr->MajorFunction = IRP_MJ_SET_INFORMATION;
StackPtr->FileObject = FileObject;
/* Enter SEH */
/* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
_SEH2_TRY
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB);
/* Copy the data into it */
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
@ -3704,13 +3702,13 @@ NtUnlockFile(IN HANDLE FileHandle,
StackPtr->MinorFunction = IRP_MN_UNLOCK_SINGLE;
StackPtr->FileObject = FileObject;
/* Enter SEH */
/* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
_SEH2_TRY
{
/* Allocate a buffer */
LocalLength = ExAllocatePoolWithTag(NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK);
LocalLength = ExAllocatePoolWithQuotaTag(NonPagedPool,
sizeof(LARGE_INTEGER),
TAG_LOCK);
/* Set the length */
*LocalLength = CapturedLength;
@ -4055,14 +4053,12 @@ NtWriteFile(IN HANDLE FileHandle,
/* Check if we have a buffer length */
if (Length)
{
/* Enter SEH */
/* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
_SEH2_TRY
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB);
/* Copy the data into it */
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, Length);
@ -4293,6 +4289,7 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
{
_SEH2_VOLATILE PFILE_FS_DRIVER_PATH_INFORMATION DriverPathInfo = NULL;
/* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
_SEH2_TRY
{
/* Allocate our local structure */
@ -4383,14 +4380,12 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
StackPtr->FileObject = FileObject;
/* Enter SEH */
/* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
_SEH2_TRY
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@ -4566,14 +4561,12 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
StackPtr->FileObject = FileObject;
/* Enter SEH */
/* Enter SEH (ExAllocatePoolWithQuotaTag raises on failure!) */
_SEH2_TRY
{
/* Allocate a buffer */
Irp->AssociatedIrp.SystemBuffer =
ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
ExAllocatePoolWithQuotaTag(NonPagedPool, Length, TAG_SYSB);
/* Copy the data into it */
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, FsInformation, Length);