mirror of
https://github.com/reactos/reactos
synced 2025-10-06 00:12:51 +02:00
[SHELL32] Handle sort order in RegItems (#7906)
* [SHELL32] Handle sort order in RegItems This makes the TweakUI "First icon on desktop" setting work correctly.
This commit is contained in:
@@ -29,9 +29,9 @@ extern BOOL SHELL32_IsShellFolderNamespaceItemHidden(LPCWSTR SubKey, REFCLSID Cl
|
|||||||
|
|
||||||
static const REQUIREDREGITEM g_RequiredItems[] =
|
static const REQUIREDREGITEM g_RequiredItems[] =
|
||||||
{
|
{
|
||||||
{ CLSID_MyComputer, "sysdm.cpl", 0x50 },
|
{ CLSID_MyComputer, "sysdm.cpl", REGITEMORDER_MYCOMPUTER },
|
||||||
{ CLSID_NetworkPlaces, "ncpa.cpl", 0x58 },
|
{ CLSID_NetworkPlaces, "ncpa.cpl", REGITEMORDER_NETHOOD },
|
||||||
{ CLSID_Internet, "inetcpl.cpl", 0x68 },
|
{ CLSID_Internet, "inetcpl.cpl", REGITEMORDER_INTERNET },
|
||||||
};
|
};
|
||||||
static const REGFOLDERINFO g_RegFolderInfo =
|
static const REGFOLDERINFO g_RegFolderInfo =
|
||||||
{
|
{
|
||||||
|
@@ -60,7 +60,7 @@ static int iDriveTypeIds[7] = { IDS_DRIVE_FIXED, /* DRIVE_UNKNOWN */
|
|||||||
|
|
||||||
static const REQUIREDREGITEM g_RequiredItems[] =
|
static const REQUIREDREGITEM g_RequiredItems[] =
|
||||||
{
|
{
|
||||||
{ CLSID_ControlPanel, 0, 0x50 },
|
{ CLSID_ControlPanel, NULL, REGITEMORDER_MYCOMPUTER_CONTROLS },
|
||||||
};
|
};
|
||||||
static const REGFOLDERINFO g_RegFolderInfo =
|
static const REGFOLDERINFO g_RegFolderInfo =
|
||||||
{
|
{
|
||||||
|
@@ -25,17 +25,49 @@
|
|||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL (shell);
|
WINE_DEFAULT_DEBUG_CHANNEL (shell);
|
||||||
|
|
||||||
#define DEFAULTSORTORDERINDEX 0x80 // The default for registry items according to Geoff Chappell
|
|
||||||
|
|
||||||
static HRESULT CRegItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl,
|
static HRESULT CRegItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl,
|
||||||
PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, IContextMenu **ppcm);
|
PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, IContextMenu **ppcm);
|
||||||
|
|
||||||
|
HRESULT FormatGUIDKey(LPWSTR KeyName, SIZE_T KeySize, LPCWSTR RegPath, const GUID* riid)
|
||||||
|
{
|
||||||
|
WCHAR xriid[CHARS_IN_GUID];
|
||||||
|
StringFromGUID2(*riid, xriid, _countof(xriid));
|
||||||
|
return StringCchPrintfW(KeyName, KeySize, RegPath, xriid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD SHELL_QueryCLSIDValue(_In_ REFCLSID clsid, _In_opt_ LPCWSTR SubKey, _In_opt_ LPCWSTR Value, _In_opt_ PVOID pData, _In_opt_ PDWORD pSize)
|
||||||
|
{
|
||||||
|
const UINT cchGuid = CHARS_IN_GUID - 1, cchClsidSlash = sizeof("CLSID\\") - 1;
|
||||||
|
WCHAR Path[200];
|
||||||
|
wcscpy(Path, L"CLSID\\");
|
||||||
|
StringFromGUID2(clsid, Path + 6, CHARS_IN_GUID);
|
||||||
|
if (SubKey)
|
||||||
|
{
|
||||||
|
*(Path + cchClsidSlash + cchGuid) = L'\\';
|
||||||
|
wcscpy(Path + cchClsidSlash + cchGuid + 1, SubKey);
|
||||||
|
}
|
||||||
|
return RegGetValueW(HKEY_CLASSES_ROOT, Path, Value, RRF_RT_ANY, NULL, pData, pSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool HasCLSIDShellFolderValue(REFCLSID clsid, LPCWSTR Value)
|
||||||
|
{
|
||||||
|
return SHELL_QueryCLSIDValue(clsid, L"ShellFolder", Value, NULL, NULL) == ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static inline UINT GetRegItemCLSIDOffset(PIDLTYPE type)
|
static inline UINT GetRegItemCLSIDOffset(PIDLTYPE type)
|
||||||
{
|
{
|
||||||
return type == PT_CONTROLS_NEWREGITEM ? 14 : 4;
|
return type == PT_CONTROLS_NEWREGITEM ? 14 : 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LPITEMIDLIST CreateRegItem(PIDLTYPE type, REFCLSID clsid, BYTE order = 0)
|
static BYTE GetRegItemOrder(REFCLSID clsid)
|
||||||
|
{
|
||||||
|
DWORD dwOrder, cb = sizeof(dwOrder);
|
||||||
|
if (SHELL_QueryCLSIDValue(clsid, NULL, L"SortOrderIndex", &dwOrder, &cb) || cb != sizeof(dwOrder))
|
||||||
|
dwOrder = REGITEMORDER_DEFAULT;
|
||||||
|
return (BYTE)dwOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPITEMIDLIST CreateRegItem(PIDLTYPE type, REFCLSID clsid, int order = -1)
|
||||||
{
|
{
|
||||||
#if 1 // FIXME: CControlPanelFolder is not ready for this yet
|
#if 1 // FIXME: CControlPanelFolder is not ready for this yet
|
||||||
if (type == PT_CONTROLS_NEWREGITEM)
|
if (type == PT_CONTROLS_NEWREGITEM)
|
||||||
@@ -49,7 +81,7 @@ static LPITEMIDLIST CreateRegItem(PIDLTYPE type, REFCLSID clsid, BYTE order = 0)
|
|||||||
ZeroMemory(pidl, cbTotal); // Note: This also initializes the terminator WORD
|
ZeroMemory(pidl, cbTotal); // Note: This also initializes the terminator WORD
|
||||||
pidl->mkid.cb = cb;
|
pidl->mkid.cb = cb;
|
||||||
pidl->mkid.abID[0] = type;
|
pidl->mkid.abID[0] = type;
|
||||||
pidl->mkid.abID[1] = order;
|
pidl->mkid.abID[1] = order >= 0 ? (BYTE)order : GetRegItemOrder(clsid);
|
||||||
*(CLSID*)(SIZE_T(pidl) + offset) = clsid;
|
*(CLSID*)(SIZE_T(pidl) + offset) = clsid;
|
||||||
}
|
}
|
||||||
return pidl;
|
return pidl;
|
||||||
@@ -61,31 +93,6 @@ static LPITEMIDLIST CreateRegItem(PIDLTYPE type, LPCWSTR clsidstr)
|
|||||||
return SUCCEEDED(CLSIDFromString(clsidstr, &clsid)) ? CreateRegItem(type, clsid) : NULL;
|
return SUCCEEDED(CLSIDFromString(clsidstr, &clsid)) ? CreateRegItem(type, clsid) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT FormatGUIDKey(LPWSTR KeyName, SIZE_T KeySize, LPCWSTR RegPath, const GUID* riid)
|
|
||||||
{
|
|
||||||
WCHAR xriid[CHARS_IN_GUID];
|
|
||||||
StringFromGUID2(*riid, xriid, _countof(xriid));
|
|
||||||
return StringCchPrintfW(KeyName, KeySize, RegPath, xriid);
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWORD SHELL_QueryCLSIDValue(_In_ REFCLSID clsid, _In_opt_ LPCWSTR SubKey, _In_opt_ LPCWSTR Value, _In_opt_ PVOID pData, _In_opt_ PDWORD pSize)
|
|
||||||
{
|
|
||||||
WCHAR Path[MAX_PATH];
|
|
||||||
wcscpy(Path, L"CLSID\\");
|
|
||||||
StringFromGUID2(clsid, Path + 6, 39);
|
|
||||||
if (SubKey)
|
|
||||||
{
|
|
||||||
wcscpy(Path + 6 + 38, L"\\");
|
|
||||||
wcscpy(Path + 6 + 39, SubKey);
|
|
||||||
}
|
|
||||||
return RegGetValueW(HKEY_CLASSES_ROOT, Path, Value, RRF_RT_ANY, NULL, pData, pSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool HasCLSIDShellFolderValue(REFCLSID clsid, LPCWSTR Value)
|
|
||||||
{
|
|
||||||
return SHELL_QueryCLSIDValue(clsid, L"ShellFolder", Value, NULL, NULL) == ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CRegFolderInfo
|
struct CRegFolderInfo
|
||||||
{
|
{
|
||||||
const REGFOLDERINFO *m_pInfo;
|
const REGFOLDERINFO *m_pInfo;
|
||||||
@@ -118,6 +125,12 @@ struct CRegFolderInfo
|
|||||||
return CreateRegItem(GetPidlType(), item.clsid, item.Order);
|
return CreateRegItem(GetPidlType(), item.clsid, item.Order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WORD GetRegItemOrder(LPCITEMIDLIST pidl) const
|
||||||
|
{
|
||||||
|
const CLSID *pCLSID = IsRegItem(pidl);
|
||||||
|
return pCLSID ? ::GetRegItemOrder(*pCLSID) : 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
LPCWSTR GetParsingPath() const { return m_pInfo->pszParsingPath; }
|
LPCWSTR GetParsingPath() const { return m_pInfo->pszParsingPath; }
|
||||||
UINT GetCLSIDOffset() const { return GetRegItemCLSIDOffset(m_pInfo->PidlType); }
|
UINT GetCLSIDOffset() const { return GetRegItemCLSIDOffset(m_pInfo->PidlType); }
|
||||||
PIDLTYPE GetPidlType() const { return m_pInfo->PidlType; }
|
PIDLTYPE GetPidlType() const { return m_pInfo->PidlType; }
|
||||||
@@ -314,6 +327,7 @@ class CRegFolder :
|
|||||||
IShellFolder *m_pOuterFolder; // Not ref-counted
|
IShellFolder *m_pOuterFolder; // Not ref-counted
|
||||||
CComHeapPtr<ITEMIDLIST> m_pidlRoot;
|
CComHeapPtr<ITEMIDLIST> m_pidlRoot;
|
||||||
|
|
||||||
|
HRESULT CompareRegItemsSortOrder(PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2);
|
||||||
HRESULT GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
|
HRESULT GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
|
||||||
BOOL _IsInNameSpace(_In_ LPCITEMIDLIST pidl);
|
BOOL _IsInNameSpace(_In_ LPCITEMIDLIST pidl);
|
||||||
|
|
||||||
@@ -514,6 +528,18 @@ HRESULT WINAPI CRegFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserv
|
|||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT CRegFolder::CompareRegItemsSortOrder(PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
|
||||||
|
{
|
||||||
|
LPPIDLDATA p1 = (LPPIDLDATA)pidl1->mkid.abID;
|
||||||
|
LPPIDLDATA p2 = (LPPIDLDATA)pidl2->mkid.abID;
|
||||||
|
int Order1 = p1->u.guid.uSortOrder > 0x40 ? p1->u.guid.uSortOrder : GetRegItemOrder(pidl1);
|
||||||
|
int Order2 = p2->u.guid.uSortOrder > 0x40 ? p2->u.guid.uSortOrder : GetRegItemOrder(pidl2);
|
||||||
|
int Cmp = Order1 - Order2;
|
||||||
|
if (Cmp != 0)
|
||||||
|
return MAKE_COMPARE_HRESULT(Cmp);
|
||||||
|
return SHELL32_CompareDetails(this, COL_NAME, pidl1, pidl2);
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT WINAPI CRegFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
|
HRESULT WINAPI CRegFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
|
||||||
{
|
{
|
||||||
if (!pidl1 || !pidl2 || pidl1->mkid.cb == 0 || pidl2->mkid.cb == 0)
|
if (!pidl1 || !pidl2 || pidl1->mkid.cb == 0 || pidl2->mkid.cb == 0)
|
||||||
@@ -532,6 +558,12 @@ HRESULT WINAPI CRegFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, P
|
|||||||
}
|
}
|
||||||
else if (clsid1 && clsid2)
|
else if (clsid1 && clsid2)
|
||||||
{
|
{
|
||||||
|
if ((lParam & SHCIDS_COLUMNMASK) == COL_NAME && !(lParam & SHCIDS_CANONICALONLY))
|
||||||
|
{
|
||||||
|
HRESULT hrCmpOrder = CompareRegItemsSortOrder(pidl1, pidl2);
|
||||||
|
if (hrCmpOrder && SUCCEEDED(hrCmpOrder))
|
||||||
|
return hrCmpOrder;
|
||||||
|
}
|
||||||
if (memcmp(clsid1, clsid2, sizeof(GUID)) == 0)
|
if (memcmp(clsid1, clsid2, sizeof(GUID)) == 0)
|
||||||
return SHELL32_CompareChildren(this, lParam, pidl1, pidl2);
|
return SHELL32_CompareChildren(this, lParam, pidl1, pidl2);
|
||||||
|
|
||||||
|
@@ -1798,19 +1798,19 @@ LPITEMIDLIST _ILCreateDesktop(void)
|
|||||||
LPITEMIDLIST _ILCreateMyComputer(void)
|
LPITEMIDLIST _ILCreateMyComputer(void)
|
||||||
{
|
{
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyComputer);
|
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyComputer, REGITEMORDER_MYCOMPUTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
LPITEMIDLIST _ILCreateMyDocuments(void)
|
LPITEMIDLIST _ILCreateMyDocuments(void)
|
||||||
{
|
{
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyDocuments);
|
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_MyDocuments, REGITEMORDER_MYDOCS_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
LPITEMIDLIST _ILCreateIExplore(void)
|
LPITEMIDLIST _ILCreateIExplore(void)
|
||||||
{
|
{
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_Internet);
|
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_Internet, REGITEMORDER_INTERNET);
|
||||||
}
|
}
|
||||||
|
|
||||||
LPITEMIDLIST _ILCreateControlPanel(void)
|
LPITEMIDLIST _ILCreateControlPanel(void)
|
||||||
@@ -1820,7 +1820,7 @@ LPITEMIDLIST _ILCreateControlPanel(void)
|
|||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
if (parent)
|
if (parent)
|
||||||
{
|
{
|
||||||
LPITEMIDLIST cpl = _ILCreateGuid(PT_COMPUTER_REGITEM, &CLSID_ControlPanel);
|
LPITEMIDLIST cpl = _ILCreateGuid(PT_COMPUTER_REGITEM, &CLSID_ControlPanel, REGITEMORDER_MYCOMPUTER_CONTROLS);
|
||||||
if (cpl)
|
if (cpl)
|
||||||
{
|
{
|
||||||
ret = ILCombine(parent, cpl);
|
ret = ILCombine(parent, cpl);
|
||||||
@@ -1861,22 +1861,22 @@ LPITEMIDLIST _ILCreatePrinters(void)
|
|||||||
LPITEMIDLIST _ILCreateNetwork(void)
|
LPITEMIDLIST _ILCreateNetwork(void)
|
||||||
{
|
{
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_NetworkPlaces);
|
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_NetworkPlaces, REGITEMORDER_NETHOOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
LPITEMIDLIST _ILCreateBitBucket(void)
|
LPITEMIDLIST _ILCreateBitBucket(void)
|
||||||
{
|
{
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_RecycleBin);
|
return _ILCreateGuid(PT_DESKTOP_REGITEM, &CLSID_RecycleBin, REGITEMORDER_RECYCLEBIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
LPITEMIDLIST _ILCreateAdminTools(void)
|
LPITEMIDLIST _ILCreateAdminTools(void)
|
||||||
{
|
{
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
return _ILCreateGuid(PT_GUID, &CLSID_AdminFolderShortcut); //FIXME
|
return _ILCreateGuid(PT_GUID, &CLSID_AdminFolderShortcut, REGITEMORDER_DEFAULT); //FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid)
|
LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid, BYTE SortOrder)
|
||||||
{
|
{
|
||||||
LPITEMIDLIST pidlOut;
|
LPITEMIDLIST pidlOut;
|
||||||
|
|
||||||
@@ -1886,7 +1886,7 @@ LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid)
|
|||||||
if (pidlOut)
|
if (pidlOut)
|
||||||
{
|
{
|
||||||
LPPIDLDATA pData = _ILGetDataPointer(pidlOut);
|
LPPIDLDATA pData = _ILGetDataPointer(pidlOut);
|
||||||
|
pData->u.guid.uSortOrder = SortOrder;
|
||||||
pData->u.guid.guid = *guid;
|
pData->u.guid.guid = *guid;
|
||||||
TRACE("-- create GUID-pidl %s\n",
|
TRACE("-- create GUID-pidl %s\n",
|
||||||
debugstr_guid(&(pData->u.guid.guid)));
|
debugstr_guid(&(pData->u.guid.guid)));
|
||||||
|
@@ -119,7 +119,27 @@ extern "C" {
|
|||||||
#define PT_INTERNET_URL 0x61
|
#define PT_INTERNET_URL 0x61
|
||||||
#define PT_CONTROLS_OLDREGITEM 0x70
|
#define PT_CONTROLS_OLDREGITEM 0x70
|
||||||
#define PT_CONTROLS_NEWREGITEM 0x71
|
#define PT_CONTROLS_NEWREGITEM 0x71
|
||||||
|
|
||||||
|
#define REGITEMLOCATION_CONTROLS CSIDL_DRIVES
|
||||||
|
#define REGITEMLOCATION_PRINTERS CSIDL_CONTROLS
|
||||||
|
|
||||||
|
#define REGITEMORDER_DEFAULT 0x80
|
||||||
|
#define REGITEMORDER_LIBRARIES 0x42
|
||||||
|
#define REGITEMORDER_USERSFILEFOLDER 0x44
|
||||||
|
#define REGITEMORDER_MYCOMPUTER 0x50
|
||||||
|
#define REGITEMORDER_MYDOCS_BEFOREMYCOMPUTER 0x48 // Tweak UI "Desktop => First Icon" only
|
||||||
|
#define REGITEMORDER_MYDOCS_AFTERMYCOMPUTER 0x54 // accepts these two values.
|
||||||
|
#define REGITEMORDER_MYDOCS_DEFAULT 0x48
|
||||||
|
#define REGITEMORDER_NETHOOD 0x58
|
||||||
|
#if (REGITEMLOCATION_CONTROLS == CSIDL_DESKTOP)
|
||||||
|
#define REGITEMORDER_RECYCLEBIN 0x78
|
||||||
|
#else
|
||||||
|
#define REGITEMORDER_RECYCLEBIN 0x60
|
||||||
#endif
|
#endif
|
||||||
|
#define REGITEMORDER_INTERNET 0x68
|
||||||
|
#define REGITEMORDER_DESKTOP_CONTROLS 0x70 // NT6
|
||||||
|
#define REGITEMORDER_MYCOMPUTER_CONTROLS 0x1E // NT5
|
||||||
|
#endif // __REACTOS__
|
||||||
|
|
||||||
static inline BYTE _ILGetType(LPCITEMIDLIST pidl)
|
static inline BYTE _ILGetType(LPCITEMIDLIST pidl)
|
||||||
{
|
{
|
||||||
@@ -165,7 +185,7 @@ typedef struct tagPIDLPrinterStruct
|
|||||||
|
|
||||||
typedef struct tagGUIDStruct
|
typedef struct tagGUIDStruct
|
||||||
{
|
{
|
||||||
BYTE dummy; /* offset 01 is unknown */
|
BYTE uSortOrder;
|
||||||
GUID guid; /* offset 02 */
|
GUID guid; /* offset 02 */
|
||||||
} GUIDStruct;
|
} GUIDStruct;
|
||||||
|
|
||||||
@@ -269,7 +289,7 @@ UINT _ILGetDepth(LPCITEMIDLIST pidl);
|
|||||||
/* Creates a PIDL with guid format and type type, which must be one of PT_GUID,
|
/* Creates a PIDL with guid format and type type, which must be one of PT_GUID,
|
||||||
* PT_SHELLEXT, or PT_YAGUID.
|
* PT_SHELLEXT, or PT_YAGUID.
|
||||||
*/
|
*/
|
||||||
LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid) DECLSPEC_HIDDEN;
|
LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, REFIID guid, BYTE SortOrder);
|
||||||
|
|
||||||
#ifndef __REACTOS__
|
#ifndef __REACTOS__
|
||||||
/* Like _ILCreateGuid, but using the string szGUID. */
|
/* Like _ILCreateGuid, but using the string szGUID. */
|
||||||
|
Reference in New Issue
Block a user