mirror of https://github.com/reactos/reactos.git
Compare commits
33 Commits
9e7c55f357
...
b88bd4f292
Author | SHA1 | Date |
---|---|---|
Mahmoud Ahmed | b88bd4f292 | |
Marcin Jabłoński | dcf9eb060a | |
Timo Kreuzer | 45aa8f8111 | |
Timo Kreuzer | 6beff505d7 | |
Thamatip Chitpong | cd0bb1af07 | |
Thamatip Chitpong | 6d16d27462 | |
Thamatip Chitpong | 018264f38f | |
Katayama Hirofumi MZ | 1331e2fb02 | |
Doug Lyons | 3693d55404 | |
Timo Kreuzer | 1f49173f82 | |
Timo Kreuzer | 3c55252828 | |
Timo Kreuzer | f319538d98 | |
Timo Kreuzer | 0ea48e79fc | |
Timo Kreuzer | 43beb913da | |
Katayama Hirofumi MZ | d55f49978d | |
Katayama Hirofumi MZ | 91acf823d8 | |
Katayama Hirofumi MZ | c0c270e90e | |
Katayama Hirofumi MZ | 75cc5b2b1c | |
Katayama Hirofumi MZ | 8337df2bd1 | |
Oleg Dubinskiy | 24e088daa8 | |
TabbyDev | 8bf0f03a3d | |
TabbyDev | 00f360fc84 | |
Stanislav Motylkov | 04806f528c | |
Stanislav Motylkov | 5579d260a4 | |
TabbyDev | 89ddff351b | |
TabbyDev | f9a1f8a5ac | |
TabbyDev | 195d82c1c0 | |
TabbyDev | 81ddcfca71 | |
TabbyDev | de676b5288 | |
TabbyDev | 3906df5562 | |
TabbyDev | 7e6358ba78 | |
TabbyDev | ccdc53f41d | |
TabbyDev | 758606af0b |
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* PROJECT: ReactOS WineMine
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Arabic (Egypt) resource file
|
||||
* TRANSLATOR: Copyright 2024 Mahmoud Ahmed <tabs90600@gmail.com>
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_ARABIC, SUBLANG_ARABIC_EGYPT
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_APPNAME "WineMine"
|
||||
IDS_NOBODY "لا أحد"
|
||||
IDS_ABOUT "Copyright 2000 Joshua Thielen"
|
||||
END
|
||||
|
||||
IDM_WINEMINE MENU
|
||||
BEGIN
|
||||
POPUP "الخيارات"
|
||||
BEGIN
|
||||
MENUITEM "لعبة جديدة\tF2", IDM_NEW
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "حط علامة على السؤال", IDM_MARKQ
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "مبتدئ", IDM_BEGINNER
|
||||
MENUITEM "متقدم", IDM_ADVANCED
|
||||
MENUITEM "خبير", IDM_EXPERT
|
||||
MENUITEM "اختياري...", IDM_CUSTOM
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "أخرج\tAlt+X", IDM_EXIT
|
||||
END
|
||||
POPUP "معلومات"
|
||||
BEGIN
|
||||
MENUITEM "أسرع الأوقات...", IDM_TIMES
|
||||
MENUITEM "حول", IDM_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
DLG_TIMES DIALOGEX 0, 0, 160, 80
|
||||
STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT
|
||||
CAPTION "أسرع الأوقات"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
GROUPBOX "أسرع الأوقات", -1, 10, 10, 140, 45
|
||||
LTEXT "مبتدئ", -1, 20, 20, 40, 8
|
||||
LTEXT "متقدم", -1, 20, 30, 40, 8
|
||||
LTEXT "خبير", -1, 20, 40, 40, 8
|
||||
LTEXT "999", IDC_TIME1, 70, 20, 15, 8
|
||||
LTEXT "999", IDC_TIME2, 70, 30, 15, 8
|
||||
LTEXT "999", IDC_TIME3, 70, 40, 15, 8
|
||||
LTEXT "", IDC_NAME1, 90, 20, 55, 8
|
||||
LTEXT "", IDC_NAME2, 90, 30, 55, 8
|
||||
LTEXT "", IDC_NAME3, 90, 40, 55, 8
|
||||
DEFPUSHBUTTON "اوكي", IDOK, 55, 60, 50, 15
|
||||
END
|
||||
|
||||
DLG_CONGRATS DIALOGEX 0, 0, 160, 60
|
||||
STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT
|
||||
CAPTION "مبروك!"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "أكتب أسمك", -1, 10, 10, 150, 10
|
||||
EDITTEXT IDC_EDITNAME, 25, 20, 110, 12
|
||||
DEFPUSHBUTTON "اوكي", IDOK, 60, 40, 40, 15
|
||||
END
|
||||
|
||||
DLG_CUSTOM DIALOGEX 0, 0, 100, 100
|
||||
STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT
|
||||
CAPTION "لعبه اختياريه"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Rows", -1, 5, 5, 30, 10
|
||||
LTEXT "Cols", -1, 5, 35, 30, 10
|
||||
LTEXT "Mines", -1, 5, 65, 30, 10
|
||||
EDITTEXT IDC_EDITROWS, 5, 15, 20, 12, ES_NUMBER
|
||||
EDITTEXT IDC_EDITCOLS, 5, 45, 20, 12, ES_NUMBER
|
||||
EDITTEXT IDC_EDITMINES, 5, 75, 20, 12, ES_NUMBER
|
||||
DEFPUSHBUTTON "اوكي", IDOK, 40, 30, 50, 15
|
||||
PUSHBUTTON "إلغاء", IDCANCEL, 40, 50, 50, 15
|
||||
END
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* PROJECT: ReactOS WineMine
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Arabic (Saudi Arabia) resource file
|
||||
* TRANSLATOR: Copyright 2024 Mahmoud Ahmed <tabs90600@gmail.com>
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_ARABIC, SUBLANG_ARABIC_SAUDI_ARABIA
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_APPNAME "WineMine"
|
||||
IDS_NOBODY "لا أحد"
|
||||
IDS_ABOUT "Copyright 2000 Joshua Thielen"
|
||||
END
|
||||
|
||||
IDM_WINEMINE MENU
|
||||
BEGIN
|
||||
POPUP "الخيارات"
|
||||
BEGIN
|
||||
MENUITEM "لعبة جديدة\tF2", IDM_NEW
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "ضع علامة على السؤال", IDM_MARKQ
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "مبتدئ", IDM_BEGINNER
|
||||
MENUITEM "متقدم", IDM_ADVANCED
|
||||
MENUITEM "خبير", IDM_EXPERT
|
||||
MENUITEM "اختياري...", IDM_CUSTOM
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "أخرج\tAlt+X", IDM_EXIT
|
||||
END
|
||||
POPUP "معلومات"
|
||||
BEGIN
|
||||
MENUITEM "أسرع الأوقات...", IDM_TIMES
|
||||
MENUITEM "حول", IDM_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
DLG_TIMES DIALOGEX 0, 0, 160, 80
|
||||
STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT
|
||||
CAPTION "أسرع الأوقات"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
GROUPBOX "أسرع الأوقات", -1, 10, 10, 140, 45
|
||||
LTEXT "مبتدئ", -1, 20, 20, 40, 8
|
||||
LTEXT "متقدم", -1, 20, 30, 40, 8
|
||||
LTEXT "خبير", -1, 20, 40, 40, 8
|
||||
LTEXT "999", IDC_TIME1, 70, 20, 15, 8
|
||||
LTEXT "999", IDC_TIME2, 70, 30, 15, 8
|
||||
LTEXT "999", IDC_TIME3, 70, 40, 15, 8
|
||||
LTEXT "", IDC_NAME1, 90, 20, 55, 8
|
||||
LTEXT "", IDC_NAME2, 90, 30, 55, 8
|
||||
LTEXT "", IDC_NAME3, 90, 40, 55, 8
|
||||
DEFPUSHBUTTON "OK", IDOK, 55, 60, 50, 15
|
||||
END
|
||||
|
||||
DLG_CONGRATS DIALOGEX 0, 0, 160, 60
|
||||
STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT
|
||||
CAPTION "تهانينا!"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "أدخل أسمك", -1, 10, 10, 150, 10
|
||||
EDITTEXT IDC_EDITNAME, 25, 20, 110, 12
|
||||
DEFPUSHBUTTON "نعم", IDOK, 60, 40, 40, 15
|
||||
END
|
||||
|
||||
DLG_CUSTOM DIALOGEX 0, 0, 100, 100
|
||||
STYLE DS_MODALFRAME | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_SHELLFONT
|
||||
CAPTION "لعبه اختياريه"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "Rows", -1, 5, 5, 30, 10
|
||||
LTEXT "Cols", -1, 5, 35, 30, 10
|
||||
LTEXT "Mines", -1, 5, 65, 30, 10
|
||||
EDITTEXT IDC_EDITROWS, 5, 15, 20, 12, ES_NUMBER
|
||||
EDITTEXT IDC_EDITCOLS, 5, 45, 20, 12, ES_NUMBER
|
||||
EDITTEXT IDC_EDITMINES, 5, 75, 20, 12, ES_NUMBER
|
||||
DEFPUSHBUTTON "نعم", IDOK, 40, 30, 50, 15
|
||||
PUSHBUTTON "إلغاء", IDCANCEL, 40, 50, 50, 15
|
||||
END
|
|
@ -51,6 +51,12 @@ IDI_MINES BITMAP "rc/mines.bmp"
|
|||
/* UTF-8 */
|
||||
#pragma code_page(65001)
|
||||
|
||||
#ifdef LANGUAGE_AR_SA
|
||||
#include "lang/ar-SA.rc"
|
||||
#endif
|
||||
#ifdef LANGUAGE_AR_EG
|
||||
#include "lang/ar-EG.rc"
|
||||
#endif
|
||||
#ifdef LANGUAGE_BG_BG
|
||||
#include "lang/bg-BG.rc"
|
||||
#endif
|
||||
|
|
|
@ -1222,6 +1222,7 @@ void ProcessPage_OnOpenFileLocation(void)
|
|||
DWORD dwProcessId;
|
||||
DWORD dwLength;
|
||||
LPWSTR pszExePath;
|
||||
static const WCHAR szCmdFormat[] = L"/select,\"%s\"";
|
||||
LPWSTR pszCmdLine = NULL;
|
||||
|
||||
dwProcessId = GetSelectedProcessId();
|
||||
|
@ -1240,14 +1241,18 @@ void ProcessPage_OnOpenFileLocation(void)
|
|||
goto Cleanup;
|
||||
|
||||
/* Build the shell command line */
|
||||
pszCmdLine = HeapAlloc(GetProcessHeap(), 0, (dwLength + CONST_STR_LEN(L"/select,\"\"")) * sizeof(WCHAR));
|
||||
dwLength += CONST_STR_LEN(szCmdFormat) - CONST_STR_LEN(L"%s");
|
||||
pszCmdLine = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR));
|
||||
if (!pszCmdLine)
|
||||
goto Cleanup;
|
||||
|
||||
StringCchPrintfW(pszCmdLine, dwLength + CONST_STR_LEN(L"/select,\"\""), L"/select,\"%s\"", pszExePath);
|
||||
StringCchPrintfW(pszCmdLine, dwLength, szCmdFormat, pszExePath);
|
||||
|
||||
/* Call the shell to open the file location and select it */
|
||||
ShellExecuteW(NULL, L"open", L"explorer.exe", pszCmdLine, NULL, SW_SHOWNORMAL);
|
||||
/* Call the shell to open the file location and select it. If Explorer shell
|
||||
* is not available, use ReactOS's alternative file browser instead. */
|
||||
ShellExecuteW(NULL, L"open",
|
||||
GetShellWindow() ? L"explorer.exe" : L"filebrowser.exe",
|
||||
pszCmdLine, NULL, SW_SHOWNORMAL);
|
||||
|
||||
Cleanup:
|
||||
HeapFree(GetProcessHeap(), 0, pszCmdLine);
|
||||
|
|
|
@ -550,7 +550,7 @@ HRESULT WINAPI CControlPanelFolder::GetDefaultColumnState(UINT iColumn, DWORD *p
|
|||
|
||||
if (!pcsFlags || iColumn >= CONTROLPANEL_COL_COUNT)
|
||||
return E_INVALIDARG;
|
||||
*pcsFlags = ControlPanelSFHeader[iColumn].pcsFlags;
|
||||
*pcsFlags = ControlPanelSFHeader[iColumn].colstate;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
#include "CFSFolder.h" // Only for CFSFolder::*FSColumn* helpers!
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
|
||||
|
@ -284,17 +285,6 @@ class CDesktopFolderEnum :
|
|||
|
||||
int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
|
||||
|
||||
static const shvheader DesktopSFHeader[] = {
|
||||
{IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
|
||||
{IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 10},
|
||||
{IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
|
||||
{IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
|
||||
{IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
|
||||
{IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10}
|
||||
};
|
||||
|
||||
#define DESKTOPSHELLVIEWCOLUMNS 6
|
||||
|
||||
static const DWORD dwDesktopAttributes =
|
||||
SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
|
||||
SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE;
|
||||
|
@ -978,16 +968,25 @@ HRESULT WINAPI CDesktopFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CDesktopFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
|
||||
HRESULT WINAPI CDesktopFolder::GetDefaultColumnState(UINT iColumn, SHCOLSTATEF *pcsFlags)
|
||||
{
|
||||
HRESULT hr;
|
||||
TRACE ("(%p)\n", this);
|
||||
|
||||
if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
|
||||
if (!pcsFlags)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
|
||||
|
||||
return S_OK;
|
||||
hr = CFSFolder::GetDefaultFSColumnState(iColumn, *pcsFlags);
|
||||
/*
|
||||
// CDesktopFolder may override the flags if desired (future)
|
||||
switch(iColumn)
|
||||
{
|
||||
case SHFSF_COL_FATTS:
|
||||
*pcsFlags &= ~SHCOLSTATE_ONBYDEFAULT;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CDesktopFolder::GetDetailsEx(
|
||||
|
@ -1000,19 +999,27 @@ HRESULT WINAPI CDesktopFolder::GetDetailsEx(
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Column info functions.
|
||||
* CFSFolder.h provides defaults for us.
|
||||
*/
|
||||
HRESULT CDesktopFolder::GetColumnDetails(UINT iColumn, SHELLDETAILS &sd)
|
||||
{
|
||||
/* CDesktopFolder may override the flags and/or name if desired */
|
||||
return CFSFolder::GetFSColumnDetails(iColumn, sd);
|
||||
}
|
||||
|
||||
HRESULT WINAPI CDesktopFolder::GetDetailsOf(
|
||||
PCUITEMID_CHILD pidl,
|
||||
UINT iColumn,
|
||||
SHELLDETAILS *psd)
|
||||
{
|
||||
if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
|
||||
if (!psd)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pidl)
|
||||
{
|
||||
psd->fmt = DesktopSFHeader[iColumn].fmt;
|
||||
psd->cxChar = DesktopSFHeader[iColumn].cxChar;
|
||||
return SHSetStrRet(&psd->str, DesktopSFHeader[iColumn].colnameid);
|
||||
return GetColumnDetails(iColumn, *psd);
|
||||
}
|
||||
|
||||
CComPtr<IShellFolder2> psf;
|
||||
|
|
|
@ -42,6 +42,8 @@ class CDesktopFolder :
|
|||
|
||||
HRESULT _GetSFFromPidl(LPCITEMIDLIST pidl, IShellFolder2** psf);
|
||||
|
||||
static HRESULT GetColumnDetails(UINT iColumn, SHELLDETAILS &sd);
|
||||
|
||||
HRESULT _ParseDisplayNameByParent(
|
||||
HWND hwndOwner,
|
||||
LPBC pbc,
|
||||
|
|
|
@ -1168,13 +1168,13 @@ HRESULT WINAPI CDrivesFolder::GetDefaultColumn (DWORD dwRes, ULONG *pSort, ULONG
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CDrivesFolder::GetDefaultColumnState(UINT iColumn, DWORD * pcsFlags)
|
||||
HRESULT WINAPI CDrivesFolder::GetDefaultColumnState(UINT iColumn, SHCOLSTATEF * pcsFlags)
|
||||
{
|
||||
TRACE("(%p)\n", this);
|
||||
|
||||
if (!pcsFlags || iColumn >= _countof(MyComputerSFHeader))
|
||||
return E_INVALIDARG;
|
||||
*pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
|
||||
*pcsFlags = MyComputerSFHeader[iColumn].colstate;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -527,17 +527,35 @@ CFSFolder::~CFSFolder()
|
|||
SHFree(m_sPathTarget);
|
||||
}
|
||||
|
||||
|
||||
static const shvheader GenericSFHeader[] = {
|
||||
{IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
|
||||
{IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
|
||||
{IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
|
||||
{IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
|
||||
{IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
|
||||
{IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
|
||||
{IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
|
||||
{IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 10}
|
||||
{IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR | SHCOLSTATE_SLOW, LVCFMT_LEFT, 10}, // We don't currently support comments but CRegFolder does
|
||||
};
|
||||
|
||||
#define GENERICSHELLVIEWCOLUMNS 6
|
||||
#define GENERICSHELLVIEWCOLUMNS _countof(GenericSFHeader)
|
||||
|
||||
HRESULT CFSFolder::GetFSColumnDetails(UINT iColumn, SHELLDETAILS &sd)
|
||||
{
|
||||
if (iColumn >= _countof(GenericSFHeader))
|
||||
return E_INVALIDARG;
|
||||
|
||||
sd.fmt = GenericSFHeader[iColumn].fmt;
|
||||
sd.cxChar = GenericSFHeader[iColumn].cxChar;
|
||||
return SHSetStrRet(&sd.str, GenericSFHeader[iColumn].colnameid);
|
||||
}
|
||||
|
||||
HRESULT CFSFolder::GetDefaultFSColumnState(UINT iColumn, SHCOLSTATEF &csFlags)
|
||||
{
|
||||
if (iColumn >= _countof(GenericSFHeader))
|
||||
return E_INVALIDARG;
|
||||
|
||||
csFlags = GenericSFHeader[iColumn].colstate;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT SHELL32_GetCLSIDForDirectory(LPCWSTR pwszDir, LPCWSTR KeyName, CLSID* pclsidFolder)
|
||||
{
|
||||
|
@ -1021,18 +1039,13 @@ HRESULT WINAPI CFSFolder::CompareIDs(LPARAM lParam,
|
|||
return MAKE_COMPARE_HRESULT(bIsFolder1 ? -1 : 1);
|
||||
}
|
||||
|
||||
int result;
|
||||
int result = 0;
|
||||
switch (LOWORD(lParam))
|
||||
{
|
||||
case 0: /* Name */
|
||||
case SHFSF_COL_NAME:
|
||||
result = wcsicmp(pDataW1->wszName, pDataW2->wszName);
|
||||
break;
|
||||
case 1: /* Type */
|
||||
pExtension1 = PathFindExtensionW(pDataW1->wszName);
|
||||
pExtension2 = PathFindExtensionW(pDataW2->wszName);
|
||||
result = wcsicmp(pExtension1, pExtension2);
|
||||
break;
|
||||
case 2: /* Size */
|
||||
case SHFSF_COL_SIZE:
|
||||
if (pData1->u.file.dwFileSize > pData2->u.file.dwFileSize)
|
||||
result = 1;
|
||||
else if (pData1->u.file.dwFileSize < pData2->u.file.dwFileSize)
|
||||
|
@ -1040,16 +1053,26 @@ HRESULT WINAPI CFSFolder::CompareIDs(LPARAM lParam,
|
|||
else
|
||||
result = 0;
|
||||
break;
|
||||
case 3: /* Modified */
|
||||
case SHFSF_COL_TYPE:
|
||||
pExtension1 = PathFindExtensionW(pDataW1->wszName);
|
||||
pExtension2 = PathFindExtensionW(pDataW2->wszName);
|
||||
result = wcsicmp(pExtension1, pExtension2);
|
||||
break;
|
||||
case SHFSF_COL_MDATE:
|
||||
result = pData1->u.file.uFileDate - pData2->u.file.uFileDate;
|
||||
if (result == 0)
|
||||
result = pData1->u.file.uFileTime - pData2->u.file.uFileTime;
|
||||
break;
|
||||
case 4: /* Attributes */
|
||||
case SHFSF_COL_FATTS:
|
||||
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
|
||||
case 5: /* Comments */
|
||||
case SHFSF_COL_COMMENT:
|
||||
result = 0;
|
||||
break;
|
||||
default:
|
||||
if (_ILIsPidlSimple(pidl1) || _ILIsPidlSimple(pidl2))
|
||||
ERR("Unknown column %u, can't compare\n", LOWORD(lParam));
|
||||
else
|
||||
TRACE("Unknown column %u, deferring to the subfolder\n", LOWORD(lParam));
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
|
@ -1543,16 +1566,14 @@ HRESULT WINAPI CFSFolder::GetDefaultColumn(DWORD dwRes,
|
|||
}
|
||||
|
||||
HRESULT WINAPI CFSFolder::GetDefaultColumnState(UINT iColumn,
|
||||
DWORD * pcsFlags)
|
||||
SHCOLSTATEF *pcsFlags)
|
||||
{
|
||||
TRACE ("(%p)\n", this);
|
||||
|
||||
if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS)
|
||||
if (!pcsFlags)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pcsFlags = GenericSFHeader[iColumn].pcsFlags;
|
||||
|
||||
return S_OK;
|
||||
else
|
||||
return GetDefaultFSColumnState(iColumn, *pcsFlags);
|
||||
}
|
||||
|
||||
HRESULT WINAPI CFSFolder::GetDetailsEx(PCUITEMID_CHILD pidl,
|
||||
|
@ -1576,9 +1597,7 @@ HRESULT WINAPI CFSFolder::GetDetailsOf(PCUITEMID_CHILD pidl,
|
|||
if (!pidl)
|
||||
{
|
||||
/* the header titles */
|
||||
psd->fmt = GenericSFHeader[iColumn].fmt;
|
||||
psd->cxChar = GenericSFHeader[iColumn].cxChar;
|
||||
return SHSetStrRet(&psd->str, GenericSFHeader[iColumn].colnameid);
|
||||
return GetFSColumnDetails(iColumn, *psd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1587,24 +1606,30 @@ HRESULT WINAPI CFSFolder::GetDetailsOf(PCUITEMID_CHILD pidl,
|
|||
/* the data from the pidl */
|
||||
switch (iColumn)
|
||||
{
|
||||
case 0: /* name */
|
||||
case SHFSF_COL_NAME:
|
||||
hr = GetDisplayNameOf (pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
|
||||
break;
|
||||
case 1: /* type */
|
||||
_ILGetFileType(pidl, psd->str.cStr, MAX_PATH);
|
||||
break;
|
||||
case 2: /* size */
|
||||
case SHFSF_COL_SIZE:
|
||||
_ILGetFileSize(pidl, psd->str.cStr, MAX_PATH);
|
||||
break;
|
||||
case 3: /* date */
|
||||
case SHFSF_COL_TYPE:
|
||||
_ILGetFileType(pidl, psd->str.cStr, MAX_PATH);
|
||||
break;
|
||||
case SHFSF_COL_MDATE:
|
||||
_ILGetFileDate(pidl, psd->str.cStr, MAX_PATH);
|
||||
break;
|
||||
case 4: /* attributes */
|
||||
case SHFSF_COL_FATTS:
|
||||
_ILGetFileAttributes(pidl, psd->str.cStr, MAX_PATH);
|
||||
break;
|
||||
case 5: /* FIXME: comments */
|
||||
psd->str.cStr[0] = 0;
|
||||
case SHFSF_COL_COMMENT:
|
||||
psd->str.cStr[0] = '\0'; // TODO: Extract comment from .lnk files? desktop.ini?
|
||||
break;
|
||||
#if DBG
|
||||
default:
|
||||
ERR("Missing case for column %d\n", iColumn);
|
||||
#else
|
||||
DEFAULT_UNREACHABLE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -125,6 +125,11 @@ class CFSFolder :
|
|||
|
||||
protected:
|
||||
HRESULT WINAPI GetCustomViewInfo(ULONG unknown, SFVM_CUSTOMVIEWINFO_DATA *data);
|
||||
|
||||
public:
|
||||
// Helper functions shared with CDesktopFolder
|
||||
static HRESULT GetFSColumnDetails(UINT iColumn, SHELLDETAILS &sd);
|
||||
static HRESULT GetDefaultFSColumnState(UINT iColumn, SHCOLSTATEF &csFlags);
|
||||
};
|
||||
|
||||
#endif /* _CFSFOLDER_H_ */
|
||||
|
|
|
@ -510,13 +510,13 @@ HRESULT WINAPI CNetFolder::GetDefaultColumn (DWORD dwRes, ULONG *pSort, ULONG *p
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CNetFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
|
||||
HRESULT WINAPI CNetFolder::GetDefaultColumnState(UINT iColumn, SHCOLSTATEF *pcsFlags)
|
||||
{
|
||||
TRACE("(%p)\n", this);
|
||||
|
||||
if (!pcsFlags || iColumn >= NETWORKPLACESSHELLVIEWCOLUMNS)
|
||||
return E_INVALIDARG;
|
||||
*pcsFlags = NetworkPlacesSFHeader[iColumn].pcsFlags;
|
||||
*pcsFlags = NetworkPlacesSFHeader[iColumn].colstate;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -432,11 +432,11 @@ HRESULT WINAPI CPrinterFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI CPrinterFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
|
||||
HRESULT WINAPI CPrinterFolder::GetDefaultColumnState(UINT iColumn, SHCOLSTATEF *pcsFlags)
|
||||
{
|
||||
if (!pcsFlags || iColumn >= PrinterSHELLVIEWCOLUMNS)
|
||||
return E_INVALIDARG;
|
||||
*pcsFlags = PrinterSFHeader[iColumn].pcsFlags;
|
||||
*pcsFlags = PrinterSFHeader[iColumn].colstate;
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
|
|
@ -233,14 +233,6 @@ class CRegFolderEnum :
|
|||
END_COM_MAP()
|
||||
};
|
||||
|
||||
enum registry_columns
|
||||
{
|
||||
REGISTRY_COL_NAME,
|
||||
REGISTRY_COL_TYPE,
|
||||
REGISTRY_COL_VALUE,
|
||||
REGISTRY_COL_COUNT,
|
||||
};
|
||||
|
||||
CRegFolderEnum::CRegFolderEnum()
|
||||
{
|
||||
}
|
||||
|
@ -302,6 +294,18 @@ HRESULT CRegFolderEnum::AddItemsFromKey(HKEY hkey_root, LPCWSTR szRepPath)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* These columns try to map to CFSFolder's columns because the CDesktopFolder
|
||||
* displays CFSFolder and CRegFolder items in the same view.
|
||||
*/
|
||||
enum REGFOLDERCOLUMNINDEX
|
||||
{
|
||||
COL_NAME = SHFSF_COL_NAME,
|
||||
COL_TYPE = SHFSF_COL_TYPE,
|
||||
COL_INFOTIP = SHFSF_COL_COMMENT,
|
||||
REGFOLDERCOLUMNCOUNT = max(COL_INFOTIP, COL_TYPE) + 1
|
||||
};
|
||||
|
||||
class CRegFolder :
|
||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IShellFolder2
|
||||
|
@ -808,7 +812,7 @@ HRESULT WINAPI CRegFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pD
|
|||
|
||||
HRESULT WINAPI CRegFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
|
||||
{
|
||||
if (iColumn >= REGISTRY_COL_COUNT)
|
||||
if (iColumn >= REGFOLDERCOLUMNCOUNT)
|
||||
return E_INVALIDARG;
|
||||
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
|
||||
return S_OK;
|
||||
|
@ -824,6 +828,12 @@ HRESULT WINAPI CRegFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHEL
|
|||
if (!psd)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!pidl)
|
||||
{
|
||||
TRACE("CRegFolder has no column info\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
GUID const *clsid = _ILGetGUIDPointer (pidl);
|
||||
|
||||
if (!clsid)
|
||||
|
@ -834,11 +844,11 @@ HRESULT WINAPI CRegFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHEL
|
|||
|
||||
switch(iColumn)
|
||||
{
|
||||
case REGISTRY_COL_NAME:
|
||||
case COL_NAME:
|
||||
return GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
|
||||
case REGISTRY_COL_TYPE:
|
||||
case COL_TYPE:
|
||||
return SHSetStrRet(&psd->str, IDS_SYSTEMFOLDER);
|
||||
case REGISTRY_COL_VALUE:
|
||||
case COL_INFOTIP:
|
||||
HKEY hKey;
|
||||
if (!HCR_RegOpenClassIDKey(*clsid, &hKey))
|
||||
return SHSetStrRet(&psd->str, "");
|
||||
|
|
|
@ -27,11 +27,25 @@
|
|||
#define CHARS_IN_GUID 39
|
||||
|
||||
typedef struct {
|
||||
int colnameid;
|
||||
int pcsFlags;
|
||||
int fmt;
|
||||
int cxChar;
|
||||
WORD colnameid; // Column title text resource id passed to LoadString
|
||||
WORD colstate; // SHCOLSTATEF returned by IShellFolder2::GetDefaultColumnState
|
||||
// HACK: SHCOLSTATEF truncated to WORD to reduce .rdata section size
|
||||
WORD fmt; // LVCFMT_*
|
||||
WORD cxChar; // Column width hint
|
||||
} shvheader;
|
||||
/*
|
||||
* CFSFolder column indices. CDesktopFolder MUST use the same indices!
|
||||
* According to the documentation for IShellFolder2::GetDetailsOf,
|
||||
* the first 4 columns for SFGAO_FILESYSTEM items must be Name, Size, Type, Modified date
|
||||
For Details See:
|
||||
https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishellfolder2-getdetailsof
|
||||
*/
|
||||
#define SHFSF_COL_NAME 0
|
||||
#define SHFSF_COL_SIZE 1
|
||||
#define SHFSF_COL_TYPE 2 // SHGFI_TYPENAME
|
||||
#define SHFSF_COL_MDATE 3 // Modified date
|
||||
#define SHFSF_COL_FATTS 4 // File attributes
|
||||
#define SHFSF_COL_COMMENT 5
|
||||
|
||||
#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
|
||||
#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -1137,7 +1137,7 @@ list(APPEND SOURCE_MSVCRT
|
|||
# qsort_s
|
||||
# raise.c
|
||||
# rand.c
|
||||
# rand_s.c
|
||||
rand_s.c
|
||||
# realloc.c
|
||||
# remove.c
|
||||
# rename.c
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* PROJECT: ReactOS API Tests
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Tests for rand_s
|
||||
* COPYRIGHT: Copyright 2024 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include <apitest.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef TEST_STATIC_CRT
|
||||
errno_t __cdecl rand_s(_Out_ unsigned int* _RandomValue);
|
||||
#endif
|
||||
|
||||
typedef int __cdecl rand_s_t(unsigned int*);
|
||||
rand_s_t *p_rand_s;
|
||||
|
||||
void test_rand_s_performance(void)
|
||||
{
|
||||
unsigned long long start, end;
|
||||
unsigned int val;
|
||||
int i;
|
||||
|
||||
start = __rdtsc();
|
||||
for (i = 0; i < 10000; i++)
|
||||
{
|
||||
p_rand_s(&val);
|
||||
}
|
||||
end = __rdtsc();
|
||||
printf("rand_s took %llu cycles\n", end - start);
|
||||
}
|
||||
|
||||
START_TEST(rand_s)
|
||||
{
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
#ifndef TEST_STATIC_CRT
|
||||
/* Dynamically load rand_s from mvcrt */
|
||||
HMODULE msvcrt = GetModuleHandleA("msvcrt");
|
||||
p_rand_s = (rand_s_t*)GetProcAddress(msvcrt, "rand_s");
|
||||
if (!p_rand_s)
|
||||
{
|
||||
win_skip("rand_s is not available\n");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
p_rand_s = rand_s;
|
||||
#endif
|
||||
|
||||
/* Test performance */
|
||||
test_rand_s_performance();
|
||||
|
||||
/* Test with NULL pointer */
|
||||
ret = p_rand_s(NULL);
|
||||
ok(ret == EINVAL, "Expected EINVAL, got %d\n", ret);
|
||||
|
||||
/* Test with valid pointer */
|
||||
ret = p_rand_s(&val);
|
||||
ok(ret == 0, "Expected 0, got %d\n", ret);
|
||||
}
|
|
@ -13,6 +13,7 @@ list(APPEND SOURCE_STATIC
|
|||
fpcontrol.c
|
||||
mbstowcs.c
|
||||
mbtowc.c
|
||||
rand_s.c
|
||||
sprintf.c
|
||||
strcpy.c
|
||||
strlen.c
|
||||
|
|
|
@ -32,6 +32,7 @@ extern void func__vsnprintf(void);
|
|||
extern void func__vsnwprintf(void);
|
||||
extern void func_mbstowcs(void);
|
||||
extern void func_mbtowc(void);
|
||||
extern void func_rand_s(void);
|
||||
extern void func_sprintf(void);
|
||||
extern void func_strcpy(void);
|
||||
extern void func_strlen(void);
|
||||
|
@ -79,6 +80,7 @@ const struct test winetest_testlist[] =
|
|||
{ "ceil", func_ceil },
|
||||
{ "fabs", func_fabs },
|
||||
{ "floor", func_floor },
|
||||
{ "rand_s", func_rand_s },
|
||||
#ifdef _M_AMD64 // x86 / arm need fixing
|
||||
{ "fpcontrol", func_fpcontrol },
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,7 @@ list(APPEND SOURCE
|
|||
interlck.c
|
||||
IsDBCSLeadByteEx.c
|
||||
JapaneseCalendar.c
|
||||
LCMapString.c
|
||||
LoadLibraryExW.c
|
||||
lstrcpynW.c
|
||||
lstrlen.c
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* PROJECT: ReactOS api tests
|
||||
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
|
||||
* PURPOSE: Tests for LCMapString
|
||||
* COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#undef ok_wstr_
|
||||
|
||||
static void
|
||||
ok_wstr_(const char *file, int line, LPCWSTR x, LPCWSTR y)
|
||||
{
|
||||
char buf1[100], buf2[100];
|
||||
lstrcpynA(buf1, wine_dbgstr_w(x), _countof(buf1));
|
||||
lstrcpynA(buf2, wine_dbgstr_w(y), _countof(buf2));
|
||||
ok_(file, line)(wcscmp(x, y) == 0, "Wrong string. Expected %s, got %s\n", buf2, buf1);
|
||||
}
|
||||
|
||||
#undef ok_wstr
|
||||
#define ok_wstr(x, y) ok_wstr_(__FILE__, __LINE__, x, y)
|
||||
|
||||
// "ABab12ABab12あアばバパ万萬" in UTF-16
|
||||
static const WCHAR c_target[] =
|
||||
L"ABab12\xff21\xff22\xff41\xff42\xff11\xff12\x3042\x30a2\x3070\x30d0\xff8a\xff9f\x4e07\x842c";
|
||||
|
||||
static void TEST_LCMapStringW(void)
|
||||
{
|
||||
WCHAR results[100];
|
||||
|
||||
LCMapStringW(0, LCMAP_FULLWIDTH, c_target, -1, results, _countof(results));
|
||||
ok_wstr(results, L"\xff21\xff22\xff41\xff42\xff11\xff12\xff21\xff22\xff41\xff42\xff11\xff12\x3042\x30a2\x3070\x30d0\x30d1\x4e07\x842c");
|
||||
|
||||
LCMapStringW(0, LCMAP_HALFWIDTH, c_target, -1, results, _countof(results));
|
||||
ok_wstr(results, L"ABab12ABab12\x3042\xff71\x3070\xff8a\xff9e\xff8a\xff9f\x4e07\x842c");
|
||||
|
||||
LCMapStringW(0, LCMAP_HIRAGANA, c_target, -1, results, _countof(results));
|
||||
ok_wstr(results, L"ABab12\xff21\xff22\xff41\xff42\xff11\xff12\x3042\x3042\x3070\x3070\xff8a\xff9f\x4e07\x842c");
|
||||
|
||||
LCMapStringW(0, LCMAP_KATAKANA, c_target, -1, results, _countof(results));
|
||||
ok_wstr(results, L"ABab12\xff21\xff22\xff41\xff42\xff11\xff12\x30a2\x30a2\x30d0\x30d0\xff8a\xff9f\x4e07\x842c");
|
||||
|
||||
LCMapStringW(0, LCMAP_LOWERCASE, c_target, -1, results, _countof(results));
|
||||
ok_wstr(results, L"abab12\xff41\xff42\xff41\xff42\xff11\xff12\x3042\x30a2\x3070\x30d0\xff8a\xff9f\x4e07\x842c");
|
||||
|
||||
LCMapStringW(0, LCMAP_UPPERCASE, c_target, -1, results, _countof(results));
|
||||
ok_wstr(results, L"ABAB12\xff21\xff22\xff21\xff22\xff11\xff12\x3042\x30a2\x3070\x30d0\xff8a\xff9f\x4e07\x842c");
|
||||
|
||||
LCMapStringW(0, LCMAP_SIMPLIFIED_CHINESE, c_target, -1, results, _countof(results));
|
||||
ok_wstr(results, L"ABab12\xff21\xff22\xff41\xff42\xff11\xff12\x3042\x30a2\x3070\x30d0\xff8a\xff9f\x4e07\x4e07");
|
||||
|
||||
LCMapStringW(0, LCMAP_TRADITIONAL_CHINESE, c_target, -1, results, _countof(results));
|
||||
ok_wstr(results, L"ABab12\xff21\xff22\xff41\xff42\xff11\xff12\x3042\x30a2\x3070\x30d0\xff8a\xff9f\x842c\x842c");
|
||||
}
|
||||
|
||||
START_TEST(LCMapString)
|
||||
{
|
||||
TEST_LCMapStringW();
|
||||
}
|
|
@ -22,6 +22,7 @@ extern void func_InitOnce(void);
|
|||
extern void func_interlck(void);
|
||||
extern void func_IsDBCSLeadByteEx(void);
|
||||
extern void func_JapaneseCalendar(void);
|
||||
extern void func_LCMapString(void);
|
||||
extern void func_LoadLibraryExW(void);
|
||||
extern void func_lstrcpynW(void);
|
||||
extern void func_lstrlen(void);
|
||||
|
@ -59,6 +60,7 @@ const struct test winetest_testlist[] =
|
|||
{ "interlck", func_interlck },
|
||||
{ "IsDBCSLeadByteEx", func_IsDBCSLeadByteEx },
|
||||
{ "JapaneseCalendar", func_JapaneseCalendar },
|
||||
{ "LCMapString", func_LCMapString },
|
||||
{ "LoadLibraryExW", func_LoadLibraryExW },
|
||||
{ "lstrcpynW", func_lstrcpynW },
|
||||
{ "lstrlen", func_lstrlen },
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "shell32_apitest_sub.h"
|
||||
#include <assert.h>
|
||||
|
||||
#define NUM_STAGE 4
|
||||
#define NUM_STEP 8
|
||||
#define NUM_CHECKS 12
|
||||
#define INTERVAL 0
|
||||
|
@ -89,24 +88,6 @@ static void TEST_Quit(void)
|
|||
DoDeleteFilesAndDirs();
|
||||
}
|
||||
|
||||
static BOOL FindSubProgram(void)
|
||||
{
|
||||
GetModuleFileNameW(NULL, s_szSubProgram, _countof(s_szSubProgram));
|
||||
PathRemoveFileSpecW(s_szSubProgram);
|
||||
PathAppendW(s_szSubProgram, L"shell32_apitest_sub.exe");
|
||||
|
||||
if (!PathFileExistsW(s_szSubProgram))
|
||||
{
|
||||
PathRemoveFileSpecW(s_szSubProgram);
|
||||
PathAppendW(s_szSubProgram, L"testdata\\shell32_apitest_sub.exe");
|
||||
|
||||
if (!PathFileExistsW(s_szSubProgram))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void DoBuildFilesAndDirs(void)
|
||||
{
|
||||
WCHAR szPath1[MAX_PATH];
|
||||
|
@ -236,24 +217,10 @@ static void DoStepCheck(INT iStage, INT iStep, LPCSTR checks)
|
|||
switch (iStage)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
static const TEST_ANSWER c_answers[] =
|
||||
{
|
||||
{ __LINE__, "000000010000010000000000" }, // 0
|
||||
{ __LINE__, "000000040000000000000400" }, // 1
|
||||
{ __LINE__, "000000000200020000000000" }, // 2
|
||||
{ __LINE__, "000000000000080000000000" }, // 3
|
||||
{ __LINE__, "000000000001010000000000" }, // 4
|
||||
{ __LINE__, "000000000002020000000000" }, // 5
|
||||
{ __LINE__, "000000000000000020000000" }, // 6
|
||||
{ __LINE__, "000010000000100000000000" }, // 7
|
||||
};
|
||||
C_ASSERT(_countof(c_answers) == NUM_STEP);
|
||||
lineno = c_answers[iStep].lineno;
|
||||
answer = c_answers[iStep].answer;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case 3:
|
||||
case 6:
|
||||
case 9:
|
||||
{
|
||||
static const TEST_ANSWER c_answers[] =
|
||||
{
|
||||
|
@ -272,6 +239,27 @@ static void DoStepCheck(INT iStage, INT iStep, LPCSTR checks)
|
|||
break;
|
||||
}
|
||||
case 2:
|
||||
case 4:
|
||||
case 5:
|
||||
case 7:
|
||||
{
|
||||
static const TEST_ANSWER c_answers[] =
|
||||
{
|
||||
{ __LINE__, "000000000000000000000000" }, // 0
|
||||
{ __LINE__, "000000000000000000000000" }, // 1
|
||||
{ __LINE__, "000000000000000000000000" }, // 2
|
||||
{ __LINE__, "000000000000000000000000" }, // 3
|
||||
{ __LINE__, "000000000000000000000000" }, // 4
|
||||
{ __LINE__, "000000000000000000000000" }, // 5
|
||||
{ __LINE__, "000000000000000000000000" }, // 6
|
||||
{ __LINE__, "000000000000000000000000" }, // 7
|
||||
};
|
||||
C_ASSERT(_countof(c_answers) == NUM_STEP);
|
||||
lineno = c_answers[iStep].lineno;
|
||||
answer = c_answers[iStep].answer;
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
static const TEST_ANSWER c_answers[] =
|
||||
{
|
||||
|
@ -279,8 +267,8 @@ static void DoStepCheck(INT iStage, INT iStep, LPCSTR checks)
|
|||
{ __LINE__, "000000040000000000000400" }, // 1
|
||||
{ __LINE__, "000000000200020000000000" }, // 2
|
||||
{ __LINE__, "000000000000080000000000" }, // 3
|
||||
{ __LINE__, "000000000001010000000000" }, // 4 // Recursive
|
||||
{ __LINE__, "000000000002020000000000" }, // 5 // Recursive
|
||||
{ __LINE__, "000000000001010000000000" }, // 4 // Recursive case
|
||||
{ __LINE__, "000000000002020000000000" }, // 5 // Recursive case
|
||||
{ __LINE__, "000000000000000020000000" }, // 6
|
||||
{ __LINE__, "000010000000100000000000" }, // 7
|
||||
};
|
||||
|
@ -290,30 +278,13 @@ static void DoStepCheck(INT iStage, INT iStep, LPCSTR checks)
|
|||
if (iStep == 4 || iStep == 5) // Recursive cases
|
||||
{
|
||||
if (lstrcmpA(checks, "000000000000000000000000") == 0)
|
||||
{
|
||||
trace("Warning! Recursive cases...\n");
|
||||
answer = "000000000000000000000000";
|
||||
else
|
||||
trace("Warning\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
static const TEST_ANSWER c_answers[] =
|
||||
{
|
||||
{ __LINE__, "000000010000010000000000" }, // 0
|
||||
{ __LINE__, "000000040000000000000400" }, // 1
|
||||
{ __LINE__, "000000000200020000000000" }, // 2
|
||||
{ __LINE__, "000000000000080000000000" }, // 3
|
||||
{ __LINE__, "000000000001010000000000" }, // 4 // Recursive
|
||||
{ __LINE__, "000000000002020000000000" }, // 5 // Recursive
|
||||
{ __LINE__, "000000000000000020000000" }, // 6
|
||||
{ __LINE__, "000010000000100000000000" }, // 7
|
||||
};
|
||||
C_ASSERT(_countof(c_answers) == NUM_STEP);
|
||||
lineno = c_answers[iStep].lineno;
|
||||
answer = c_answers[iStep].answer;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
assert(0);
|
||||
|
@ -334,7 +305,7 @@ static DWORD WINAPI StageThreadFunc(LPVOID arg)
|
|||
// 0: Create file1 in dir1
|
||||
s_iStep = 0;
|
||||
trace("Step %d\n", s_iStep);
|
||||
::Sleep(1000); // Extra wait
|
||||
SHChangeNotify(0, SHCNF_PATHW | SHCNF_FLUSH, NULL, NULL);
|
||||
ZeroMemory(s_abChecks, sizeof(s_abChecks));
|
||||
ret = DoCreateFile(s_szFile1InDir1);
|
||||
ok_int(ret, TRUE);
|
||||
|
@ -544,7 +515,7 @@ MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
static BOOL TEST_Init(void)
|
||||
{
|
||||
if (!FindSubProgram())
|
||||
if (!FindSubProgram(s_szSubProgram, _countof(s_szSubProgram)))
|
||||
{
|
||||
skip("shell32_apitest_sub.exe not found\n");
|
||||
return FALSE;
|
||||
|
|
|
@ -256,27 +256,6 @@ static WCHAR s_win_test_exe[MAX_PATH];
|
|||
static WCHAR s_sys_bat_file[MAX_PATH];
|
||||
static WCHAR s_cur_dir[MAX_PATH];
|
||||
|
||||
static BOOL
|
||||
GetSubProgramPath(void)
|
||||
{
|
||||
GetModuleFileNameW(NULL, s_sub_program, _countof(s_sub_program));
|
||||
PathRemoveFileSpecW(s_sub_program);
|
||||
PathAppendW(s_sub_program, L"shell32_apitest_sub.exe");
|
||||
|
||||
if (!PathFileExistsW(s_sub_program))
|
||||
{
|
||||
PathRemoveFileSpecW(s_sub_program);
|
||||
PathAppendW(s_sub_program, L"testdata\\shell32_apitest_sub.exe");
|
||||
|
||||
if (!PathFileExistsW(s_sub_program))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const TEST_ENTRY s_entries_1[] =
|
||||
{
|
||||
// NULL
|
||||
|
@ -462,11 +441,6 @@ static const TEST_ENTRY s_entries_1[] =
|
|||
{ __LINE__, TRUE, TRUE, L"shell:::{450d8fba-ad25-11d0-98a8-0800361b1103}", NULL },
|
||||
// shell:sendto
|
||||
{ __LINE__, TRUE, TRUE, L"shell:sendto", NULL },
|
||||
// iexplore.exe
|
||||
{ __LINE__, TRUE, FALSE, L"iexplore", NULL },
|
||||
{ __LINE__, TRUE, FALSE, L"iexplore.exe", NULL },
|
||||
{ __LINE__, TRUE, TRUE, L"iexplore", NULL },
|
||||
{ __LINE__, TRUE, TRUE, L"iexplore.exe", NULL },
|
||||
// https://google.com
|
||||
{ __LINE__, TRUE, FALSE, L"https://google.com", NULL },
|
||||
{ __LINE__, TRUE, TRUE, L"https://google.com", NULL },
|
||||
|
@ -677,7 +651,7 @@ START_TEST(ShellExecCmdLine)
|
|||
}
|
||||
}
|
||||
|
||||
if (!GetSubProgramPath())
|
||||
if (!FindSubProgram(s_sub_program, _countof(s_sub_program)))
|
||||
{
|
||||
skip("shell32_apitest_sub.exe is not found\n");
|
||||
return;
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
typedef enum DIRTYPE
|
||||
{
|
||||
DIRTYPE_DESKTOP = 0,
|
||||
DIRTYPE_DESKTOP_DIR,
|
||||
DIRTYPE_DRIVES,
|
||||
DIRTYPE_PRINTERS,
|
||||
DIRTYPE_DIR1,
|
||||
DIRTYPE_MAX
|
||||
} DIRTYPE;
|
||||
|
@ -24,8 +26,6 @@ static LPITEMIDLIST s_pidl[DIRTYPE_MAX];
|
|||
static UINT s_uRegID = 0;
|
||||
static INT s_iStage = -1;
|
||||
|
||||
#define NUM_STAGE 4
|
||||
|
||||
#define EVENTS (SHCNE_CREATE | SHCNE_DELETE | SHCNE_MKDIR | SHCNE_RMDIR | \
|
||||
SHCNE_RENAMEFOLDER | SHCNE_RENAMEITEM | SHCNE_UPDATEDIR | SHCNE_UPDATEITEM)
|
||||
|
||||
|
@ -40,11 +40,23 @@ inline LPITEMIDLIST DoGetPidl(INT iDir)
|
|||
SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &ret);
|
||||
break;
|
||||
}
|
||||
case DIRTYPE_DESKTOP_DIR:
|
||||
{
|
||||
WCHAR szPath1[MAX_PATH];
|
||||
SHGetSpecialFolderPathW(NULL, szPath1, CSIDL_DESKTOPDIRECTORY, FALSE);
|
||||
ret = ILCreateFromPathW(szPath1);
|
||||
break;
|
||||
}
|
||||
case DIRTYPE_DRIVES:
|
||||
{
|
||||
SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &ret);
|
||||
break;
|
||||
}
|
||||
case DIRTYPE_PRINTERS:
|
||||
{
|
||||
SHGetSpecialFolderLocation(NULL, CSIDL_PRINTERS, &ret);
|
||||
break;
|
||||
}
|
||||
case DIRTYPE_DIR1:
|
||||
{
|
||||
WCHAR szPath1[MAX_PATH];
|
||||
|
@ -85,8 +97,8 @@ static BOOL InitSHCN(HWND hwnd)
|
|||
{
|
||||
case 0:
|
||||
{
|
||||
entry.fRecursive = TRUE;
|
||||
entry.pidl = s_pidl[DIRTYPE_DESKTOP];
|
||||
entry.fRecursive = FALSE;
|
||||
entry.pidl = NULL;
|
||||
sources = SHCNRF_NewDelivery | SHCNRF_ShellLevel;
|
||||
events = EVENTS;
|
||||
break;
|
||||
|
@ -94,7 +106,7 @@ static BOOL InitSHCN(HWND hwnd)
|
|||
case 1:
|
||||
{
|
||||
entry.fRecursive = TRUE;
|
||||
entry.pidl = s_pidl[DIRTYPE_DRIVES];
|
||||
entry.pidl = NULL;
|
||||
sources = SHCNRF_NewDelivery | SHCNRF_ShellLevel;
|
||||
events = EVENTS;
|
||||
break;
|
||||
|
@ -102,12 +114,60 @@ static BOOL InitSHCN(HWND hwnd)
|
|||
case 2:
|
||||
{
|
||||
entry.fRecursive = FALSE;
|
||||
entry.pidl = s_pidl[DIRTYPE_DIR1];
|
||||
entry.pidl = s_pidl[DIRTYPE_DESKTOP];
|
||||
sources = SHCNRF_NewDelivery | SHCNRF_ShellLevel;
|
||||
events = EVENTS;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
entry.fRecursive = TRUE;
|
||||
entry.pidl = s_pidl[DIRTYPE_DESKTOP];
|
||||
sources = SHCNRF_NewDelivery | SHCNRF_ShellLevel;
|
||||
events = EVENTS;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
entry.fRecursive = TRUE;
|
||||
entry.pidl = s_pidl[DIRTYPE_DESKTOP_DIR];
|
||||
sources = SHCNRF_NewDelivery | SHCNRF_ShellLevel;
|
||||
events = EVENTS;
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
entry.fRecursive = FALSE;
|
||||
entry.pidl = s_pidl[DIRTYPE_DRIVES];
|
||||
sources = SHCNRF_NewDelivery | SHCNRF_ShellLevel;
|
||||
events = EVENTS;
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
entry.fRecursive = TRUE;
|
||||
entry.pidl = s_pidl[DIRTYPE_DRIVES];
|
||||
sources = SHCNRF_NewDelivery | SHCNRF_ShellLevel;
|
||||
events = EVENTS;
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
entry.fRecursive = TRUE;
|
||||
entry.pidl = s_pidl[DIRTYPE_PRINTERS];
|
||||
sources = SHCNRF_NewDelivery | SHCNRF_ShellLevel;
|
||||
events = EVENTS;
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
entry.fRecursive = FALSE;
|
||||
entry.pidl = s_pidl[DIRTYPE_DIR1];
|
||||
sources = SHCNRF_NewDelivery | SHCNRF_ShellLevel;
|
||||
events = EVENTS;
|
||||
break;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
entry.fRecursive = TRUE;
|
||||
entry.pidl = s_pidl[DIRTYPE_DIR1];
|
||||
|
@ -293,13 +353,19 @@ wWinMain(
|
|||
wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
|
||||
wc.lpszClassName = SUB_CLASSNAME;
|
||||
if (!RegisterClassW(&wc))
|
||||
{
|
||||
assert(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HWND hwnd = CreateWindowW(SUB_CLASSNAME, SUB_CLASSNAME, WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 400, 100,
|
||||
NULL, NULL, hInstance, NULL);
|
||||
if (!hwnd)
|
||||
{
|
||||
assert(0);
|
||||
return -2;
|
||||
}
|
||||
|
||||
ShowWindow(hwnd, SW_SHOWNORMAL);
|
||||
UpdateWindow(hwnd);
|
||||
|
|
|
@ -10,6 +10,26 @@
|
|||
|
||||
#define WM_SHELL_NOTIFY (WM_USER + 100)
|
||||
|
||||
#define NUM_STAGE 10
|
||||
|
||||
static inline BOOL FindSubProgram(LPWSTR pszSubProgram, DWORD cchSubProgram)
|
||||
{
|
||||
GetModuleFileNameW(NULL, pszSubProgram, cchSubProgram);
|
||||
PathRemoveFileSpecW(pszSubProgram);
|
||||
PathAppendW(pszSubProgram, L"shell32_apitest_sub.exe");
|
||||
|
||||
if (!PathFileExistsW(pszSubProgram))
|
||||
{
|
||||
PathRemoveFileSpecW(pszSubProgram);
|
||||
PathAppendW(pszSubProgram, L"testdata\\shell32_apitest_sub.exe");
|
||||
|
||||
if (!PathFileExistsW(pszSubProgram))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline HWND DoWaitForWindow(LPCWSTR clsname, LPCWSTR text, BOOL bClosing, BOOL bForce)
|
||||
{
|
||||
HWND hwnd = NULL;
|
||||
|
|
|
@ -54,7 +54,12 @@ extern "C" {
|
|||
#define _CRT_TERMINATE_DEFINED
|
||||
__declspec(noreturn) void __cdecl exit(_In_ int _Code);
|
||||
_CRTIMP __declspec(noreturn) void __cdecl _exit(_In_ int _Code);
|
||||
|
||||
#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */
|
||||
/* C99 function name */
|
||||
__declspec(noreturn) void __cdecl _Exit(int); /* Declare to get noreturn attribute. */
|
||||
__CRT_INLINE void __cdecl _Exit(int status)
|
||||
{ _exit(status); }
|
||||
#endif
|
||||
#if __MINGW_GNUC_PREREQ(4,4)
|
||||
#pragma push_macro("abort")
|
||||
#undef abort
|
||||
|
@ -62,7 +67,6 @@ extern "C" {
|
|||
__declspec(noreturn) void __cdecl abort(void);
|
||||
#if __MINGW_GNUC_PREREQ(4,4)
|
||||
#pragma pop_macro("abort")
|
||||
#undef abort
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -120,7 +120,6 @@ typedef struct _SOUND_OVERLAPPED
|
|||
OVERLAPPED Standard;
|
||||
struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
|
||||
PWAVEHDR Header;
|
||||
BOOL PerformCompletion;
|
||||
|
||||
LPOVERLAPPED_COMPLETION_ROUTINE OriginalCompletionRoutine;
|
||||
PVOID CompletionContext;
|
||||
|
|
|
@ -240,17 +240,12 @@ list(APPEND CRT_MATH_SOURCE
|
|||
math/ldiv.c
|
||||
math/logf.c
|
||||
math/powf.c
|
||||
math/rand.c
|
||||
)
|
||||
|
||||
list(APPEND CRT_MATH_ASM_SOURCE
|
||||
${LIBCNTPR_MATH_ASM_SOURCE}
|
||||
)
|
||||
|
||||
list(APPEND LIBCNTPR_MATH_SOURCE
|
||||
math/rand_nt.c
|
||||
)
|
||||
|
||||
if(ARCH STREQUAL "i386")
|
||||
list(APPEND ATAN2_ASM_SOURCE math/i386/atan2_asm.s)
|
||||
elseif(ARCH STREQUAL "amd64")
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
|
||||
#include <precomp.h>
|
||||
#include <ntsecapi.h>
|
||||
#include <internal/tls.h>
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
int
|
||||
rand(void)
|
||||
{
|
||||
thread_data_t *data = msvcrt_get_thread_data();
|
||||
|
||||
/* this is the algorithm used by MSVC, according to
|
||||
* http://en.wikipedia.org/wiki/List_of_pseudorandom_number_generators */
|
||||
data->random_seed = data->random_seed * 214013 + 2531011;
|
||||
return (data->random_seed >> 16) & RAND_MAX;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
void
|
||||
srand(unsigned int seed)
|
||||
{
|
||||
thread_data_t *data = msvcrt_get_thread_data();
|
||||
data->random_seed = seed;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* rand_s (MSVCRT.@)
|
||||
*/
|
||||
int CDECL rand_s(unsigned int *pval)
|
||||
{
|
||||
BOOLEAN (WINAPI *pSystemFunction036)(PVOID, ULONG); // RtlGenRandom
|
||||
HINSTANCE hadvapi32;
|
||||
|
||||
if (!pval)
|
||||
{
|
||||
_invalid_parameter(NULL,_CRT_WIDE("rand_s"),_CRT_WIDE(__FILE__),__LINE__, 0);
|
||||
*_errno() = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*pval = 0;
|
||||
hadvapi32 = LoadLibraryA("advapi32.dll");
|
||||
if (!hadvapi32)
|
||||
{
|
||||
_invalid_parameter(NULL,_CRT_WIDE("rand_s"),_CRT_WIDE(__FILE__),__LINE__, 0);
|
||||
*_errno() = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
pSystemFunction036 = (void*)GetProcAddress(hadvapi32, "SystemFunction036");
|
||||
if (!pSystemFunction036)
|
||||
{
|
||||
_invalid_parameter(NULL,_CRT_WIDE("rand_s"),_CRT_WIDE(__FILE__),__LINE__, 0);
|
||||
*_errno() = EINVAL;
|
||||
FreeLibrary(hadvapi32);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (!pSystemFunction036(pval, sizeof(*pval)))
|
||||
{
|
||||
_invalid_parameter(NULL,_CRT_WIDE("rand_s"),_CRT_WIDE(__FILE__),__LINE__, 0);
|
||||
*_errno() = EINVAL;
|
||||
FreeLibrary(hadvapi32);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
FreeLibrary(hadvapi32);
|
||||
return 0;
|
||||
}
|
|
@ -11,6 +11,13 @@ list(APPEND MSVCRTEX_SOURCE
|
|||
misc/ofmt_stub.c
|
||||
stdio/acrt_iob_func.c)
|
||||
|
||||
if(DLL_EXPORT_VERSION LESS 0x600)
|
||||
list(APPEND MSVCRTEX_SOURCE
|
||||
stdlib/_invalid_parameter.c
|
||||
stdlib/rand_s.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
# Clang performs some optimizations requiring those funtions
|
||||
list(APPEND MSVCRTEX_SOURCE
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: _invalid_parameter implementation
|
||||
* COPYRIGHT: Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
|
||||
#ifdef _MSVCRTEX_
|
||||
#undef TRACE
|
||||
#undef ERR
|
||||
#define TRACE(...)
|
||||
#define ERR(...)
|
||||
#endif
|
||||
|
||||
static _invalid_parameter_handler invalid_parameter_handler = NULL;
|
||||
|
||||
/******************************************************************************
|
||||
* _invalid_parameter (MSVCRT.@)
|
||||
*/
|
||||
void __cdecl _invalid_parameter(const wchar_t *expr, const wchar_t *func,
|
||||
const wchar_t *file, unsigned int line, uintptr_t arg)
|
||||
{
|
||||
if (invalid_parameter_handler) invalid_parameter_handler( expr, func, file, line, arg );
|
||||
else
|
||||
{
|
||||
ERR( "%s:%u %s: %s %lx\n", debugstr_w(file), line, debugstr_w(func), debugstr_w(expr), arg );
|
||||
#if _MSVCR_VER > 0 // FIXME: possible improvement: use a global variable in the DLL
|
||||
RaiseException( STATUS_INVALID_CRUNTIME_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, NULL );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* _get_invalid_parameter_handler - not exported in native msvcrt, added in msvcr80 */
|
||||
_invalid_parameter_handler CDECL _get_invalid_parameter_handler(void)
|
||||
{
|
||||
TRACE("\n");
|
||||
return invalid_parameter_handler;
|
||||
}
|
||||
|
||||
/* _set_invalid_parameter_handler - not exproted in native msvcrt, added in msvcr80 */
|
||||
_invalid_parameter_handler CDECL _set_invalid_parameter_handler(
|
||||
_invalid_parameter_handler handler)
|
||||
{
|
||||
_invalid_parameter_handler old = invalid_parameter_handler;
|
||||
|
||||
TRACE("(%p)\n", handler);
|
||||
|
||||
invalid_parameter_handler = handler;
|
||||
return old;
|
||||
}
|
|
@ -11,8 +11,6 @@
|
|||
#include <errno.h>
|
||||
#include <internal/wine/msvcrt.h>
|
||||
|
||||
static _invalid_parameter_handler invalid_parameter_handler = NULL;
|
||||
|
||||
/*********************************************************************
|
||||
* _errno (MSVCRT.@)
|
||||
*/
|
||||
|
@ -130,38 +128,3 @@ void CDECL _seterrormode(int mode)
|
|||
{
|
||||
SetErrorMode( mode );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* _invalid_parameter (MSVCRT.@)
|
||||
*/
|
||||
void __cdecl _invalid_parameter(const wchar_t *expr, const wchar_t *func,
|
||||
const wchar_t *file, unsigned int line, uintptr_t arg)
|
||||
{
|
||||
if (invalid_parameter_handler) invalid_parameter_handler( expr, func, file, line, arg );
|
||||
else
|
||||
{
|
||||
ERR( "%s:%u %s: %s %lx\n", debugstr_w(file), line, debugstr_w(func), debugstr_w(expr), arg );
|
||||
#if _MSVCR_VER > 0 // FIXME: possible improvement: use a global variable in the DLL
|
||||
RaiseException( STATUS_INVALID_CRUNTIME_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, NULL );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* _get_invalid_parameter_handler - not exported in native msvcrt, added in msvcr80 */
|
||||
_invalid_parameter_handler CDECL _get_invalid_parameter_handler(void)
|
||||
{
|
||||
TRACE("\n");
|
||||
return invalid_parameter_handler;
|
||||
}
|
||||
|
||||
/* _set_invalid_parameter_handler - not exproted in native msvcrt, added in msvcr80 */
|
||||
_invalid_parameter_handler CDECL _set_invalid_parameter_handler(
|
||||
_invalid_parameter_handler handler)
|
||||
{
|
||||
_invalid_parameter_handler old = invalid_parameter_handler;
|
||||
|
||||
TRACE("(%p)\n", handler);
|
||||
|
||||
invalid_parameter_handler = handler;
|
||||
return old;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
|
||||
#include <precomp.h>
|
||||
#include <ntsecapi.h>
|
||||
#include <internal/tls.h>
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
int
|
||||
rand(void)
|
||||
{
|
||||
thread_data_t *data = msvcrt_get_thread_data();
|
||||
|
||||
/* this is the algorithm used by MSVC, according to
|
||||
* http://en.wikipedia.org/wiki/List_of_pseudorandom_number_generators */
|
||||
data->random_seed = data->random_seed * 214013 + 2531011;
|
||||
return (data->random_seed >> 16) & RAND_MAX;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
void
|
||||
srand(unsigned int seed)
|
||||
{
|
||||
thread_data_t *data = msvcrt_get_thread_data();
|
||||
data->random_seed = seed;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: rand_s implementation
|
||||
* COPYRIGHT: Copyright 2010 Sylvain Petreolle <spetreolle@yahoo.fr>
|
||||
* Copyright 2015 Christoph von Wittich <christoph_vw@reactos.org>
|
||||
* Copyright 2015 Pierre Schweitzer <pierre@reactos.org>
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
|
||||
typedef BOOLEAN (WINAPI *PFN_SystemFunction036)(PVOID, ULONG); // RtlGenRandom
|
||||
PFN_SystemFunction036 g_pfnSystemFunction036 = NULL;
|
||||
|
||||
/*********************************************************************
|
||||
* rand_s (MSVCRT.@)
|
||||
*/
|
||||
int CDECL rand_s(unsigned int *pval)
|
||||
{
|
||||
HINSTANCE hadvapi32;
|
||||
|
||||
if (!pval)
|
||||
{
|
||||
_invalid_parameter(NULL,_CRT_WIDE("rand_s"),_CRT_WIDE(__FILE__),__LINE__, 0);
|
||||
*_errno() = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*pval = 0;
|
||||
|
||||
if (g_pfnSystemFunction036 == NULL)
|
||||
{
|
||||
PFN_SystemFunction036 pSystemFunction036;
|
||||
|
||||
hadvapi32 = LoadLibraryA("advapi32.dll");
|
||||
if (!hadvapi32)
|
||||
{
|
||||
_invalid_parameter(NULL,_CRT_WIDE("rand_s"),_CRT_WIDE(__FILE__),__LINE__, 0);
|
||||
*_errno() = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
pSystemFunction036 = (void*)GetProcAddress(hadvapi32, "SystemFunction036");
|
||||
if (!pSystemFunction036)
|
||||
{
|
||||
_invalid_parameter(NULL,_CRT_WIDE("rand_s"),_CRT_WIDE(__FILE__),__LINE__, 0);
|
||||
*_errno() = EINVAL;
|
||||
FreeLibrary(hadvapi32);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
g_pfnSystemFunction036 = pSystemFunction036;
|
||||
}
|
||||
|
||||
if (!g_pfnSystemFunction036(pval, sizeof(*pval)))
|
||||
{
|
||||
_invalid_parameter(NULL,_CRT_WIDE("rand_s"),_CRT_WIDE(__FILE__),__LINE__, 0);
|
||||
*_errno() = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Small hack: import stub to allow GCC's stdc++ to link
|
||||
#if defined(__GNUC__) && (DLL_EXPORT_VERSION < 0x600)
|
||||
#ifdef WIN64
|
||||
const void* __imp_rand_s = rand_s;
|
||||
#else
|
||||
const void* _imp_rand_s = rand_s;
|
||||
#endif
|
||||
#endif
|
|
@ -1,11 +1,17 @@
|
|||
|
||||
list(APPEND LIBCNTPR_STDLIB_SOURCE
|
||||
list(APPEND COMMON_STDLIB_SOURCE
|
||||
stdlib/qsort.c
|
||||
)
|
||||
|
||||
list(APPEND LIBCNTPR_STDLIB_SOURCE
|
||||
${COMMON_STDLIB_SOURCE}
|
||||
stdlib/rand_nt.c
|
||||
)
|
||||
|
||||
list(APPEND CRT_STDLIB_SOURCE
|
||||
${LIBCNTPR_STDLIB_SOURCE}
|
||||
${COMMON_STDLIB_SOURCE}
|
||||
stdlib/_exit.c
|
||||
stdlib/_invalid_parameter.c
|
||||
stdlib/_set_abort_behavior.c
|
||||
stdlib/abort.c
|
||||
stdlib/atexit.c
|
||||
|
@ -22,6 +28,8 @@ list(APPEND CRT_STDLIB_SOURCE
|
|||
stdlib/mbstowcs.c
|
||||
stdlib/obsol.c
|
||||
stdlib/putenv.c
|
||||
stdlib/rand.c
|
||||
stdlib/rand_s.c
|
||||
stdlib/rot.c
|
||||
stdlib/senv.c
|
||||
stdlib/swab.c
|
||||
|
|
|
@ -26,7 +26,7 @@ Unsupported MME messages:
|
|||
* Any not mentioned above
|
||||
|
||||
Notes/Bugs:
|
||||
* WHDR_BEGINLOOP and WHDR_ENDLOOP are ignored
|
||||
* WHDR_BEGINLOOP and WHDR_ENDLOOP are not working for looping multiple wave headers, only for a single header.
|
||||
* Not possible to pause/restart playback
|
||||
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
|
||||
/*
|
||||
DoWaveStreaming
|
||||
Check if there is streaming to be done, and if so, do it.
|
||||
|
@ -54,6 +53,22 @@ DoWaveStreaming(
|
|||
return;
|
||||
}
|
||||
|
||||
/* Do we need to loop a header? */
|
||||
if (DeviceType == WAVE_OUT_DEVICE_TYPE && (Header->dwFlags & WHDR_BEGINLOOP))
|
||||
{
|
||||
if ((Header->dwFlags & WHDR_ENDLOOP))
|
||||
{
|
||||
/* Get loop count */
|
||||
SoundDeviceInstance->LoopsRemaining = Header->dwLoops;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Report and help notice such a case */
|
||||
SND_WARN(L"Looping multiple headers is UNIMPLEMENTED. Will play once only\n");
|
||||
SND_ASSERT((Header->dwFlags & (WHDR_BEGINLOOP | WHDR_ENDLOOP)) == (WHDR_BEGINLOOP | WHDR_ENDLOOP));
|
||||
}
|
||||
}
|
||||
|
||||
while ( ( SoundDeviceInstance->OutstandingBuffers < SoundDeviceInstance->BufferCount ) &&
|
||||
( Header ) && SoundDeviceInstance->ResetInProgress == FALSE)
|
||||
{
|
||||
|
@ -106,10 +121,6 @@ DoWaveStreaming(
|
|||
Overlap->SoundDeviceInstance = SoundDeviceInstance;
|
||||
Overlap->Header = Header;
|
||||
|
||||
/* Don't complete this header if it's part of a loop */
|
||||
Overlap->PerformCompletion = TRUE;
|
||||
// ( SoundDeviceInstance->LoopsRemaining > 0 );
|
||||
|
||||
/* Adjust the commit-related counters */
|
||||
HeaderExtension->BytesCommitted += BytesToCommit;
|
||||
++ SoundDeviceInstance->OutstandingBuffers;
|
||||
|
@ -189,8 +200,8 @@ CompleteIO(
|
|||
-- SoundDeviceInstance->OutstandingBuffers;
|
||||
|
||||
/* Did we finish a WAVEHDR and aren't looping? */
|
||||
if ( HdrExtension->BytesCompleted + dwNumberOfBytesTransferred >= WaveHdr->dwBufferLength &&
|
||||
SoundOverlapped->PerformCompletion )
|
||||
if (HdrExtension->BytesCompleted + dwNumberOfBytesTransferred >= WaveHdr->dwBufferLength &&
|
||||
SoundDeviceInstance->LoopsRemaining == 0)
|
||||
{
|
||||
/* Wave buffer fully completed */
|
||||
Bytes = WaveHdr->dwBufferLength - HdrExtension->BytesCompleted;
|
||||
|
@ -203,9 +214,24 @@ CompleteIO(
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Partially completed */
|
||||
HdrExtension->BytesCompleted += dwNumberOfBytesTransferred;
|
||||
SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
|
||||
/* Do we loop a header? */
|
||||
if (HdrExtension->BytesCommitted == WaveHdr->dwBufferLength &&
|
||||
SoundDeviceInstance->LoopsRemaining != 0)
|
||||
{
|
||||
/* Reset amount of bytes and decrement loop count, to play next iteration */
|
||||
HdrExtension->BytesCommitted = 0;
|
||||
|
||||
if (SoundDeviceInstance->LoopsRemaining != INFINITE)
|
||||
--SoundDeviceInstance->LoopsRemaining;
|
||||
SND_TRACE(L"Looping the header, remaining loops %u\n", SoundDeviceInstance->LoopsRemaining);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Partially completed */
|
||||
HdrExtension->BytesCompleted += dwNumberOfBytesTransferred;
|
||||
SND_TRACE(L"%u/%u bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -341,6 +341,9 @@ IntDeactivateWindow(PTHREADINFO pti, HANDLE tid)
|
|||
UserDerefObjectCo(pwndFocus);
|
||||
}
|
||||
|
||||
/* Check for keyboard modifiers and release them (CORE-14768) */
|
||||
MsqReleaseModifierKeys(pti->MessageQueue);
|
||||
|
||||
if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
|
||||
if (ptiCurrent != pti)
|
||||
{
|
||||
|
|
|
@ -2530,6 +2530,21 @@ MsqSetStateWindow(PTHREADINFO pti, ULONG Type, HWND hWnd)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
MsqReleaseModifierKeys(PUSER_MESSAGE_QUEUE MessageQueue)
|
||||
{
|
||||
WORD ModifierKeys[] = { VK_LCONTROL, VK_RCONTROL, VK_CONTROL,
|
||||
VK_LMENU, VK_RMENU, VK_MENU,
|
||||
VK_LSHIFT, VK_RSHIFT, VK_SHIFT };
|
||||
UINT i;
|
||||
|
||||
for (i = 0; i < _countof(ModifierKeys); ++i)
|
||||
{
|
||||
if (IS_KEY_DOWN(MessageQueue->afKeyState, ModifierKeys[i]))
|
||||
SET_KEY_DOWN(MessageQueue->afKeyState, ModifierKeys[i], FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
SHORT
|
||||
APIENTRY
|
||||
NtUserGetKeyState(INT key)
|
||||
|
|
|
@ -288,4 +288,7 @@ co_IntWaitMessage( PWND Window,
|
|||
UINT MsgFilterMin,
|
||||
UINT MsgFilterMax );
|
||||
|
||||
VOID FASTCALL
|
||||
MsqReleaseModifierKeys(PUSER_MESSAGE_QUEUE MessageQueue);
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in New Issue