*phNewUSKey = NULL;
/* Create internal HUSKEY */
- hKey = (LPSHUSKEY)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*hKey));
+ hKey = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*hKey));
lstrcpynW(hKey->lpszPath, Path, sizeof(hKey->lpszPath));
if (hRelativeUSKey)
return ret;
}
+/*************************************************************************
+ * SHRegCreateUSKeyA [SHLWAPI.@]
+ *
+ * Create or open a user-specific registry key.
+ *
+ * PARAMS
+ * pszPath [I] Key name to create or open.
+ * samDesired [I] Wanted security access.
+ * hRelativeUSKey [I] Base path if pszPath is relative. NULL otherwise.
+ * phNewUSKey [O] Receives a handle to the new or openened key.
+ * dwFlags [I] Base key under which the key should be opened.
+ *
+ * RETURNS
+ * Success: ERROR_SUCCESS
+ * Failure: Nonzero error code from winerror.h
+ */
+LONG WINAPI SHRegCreateUSKeyA(LPCSTR pszPath, REGSAM samDesired, HUSKEY hRelativeUSKey,
+ PHUSKEY phNewUSKey, DWORD dwFlags)
+{
+ FIXME("(%s, 0x%08lx, %p, %p, 0x%08lx) stub\n", debugstr_a(pszPath), samDesired,
+ hRelativeUSKey, phNewUSKey, dwFlags);
+ return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegCreateUSKeyW [SHLWAPI.@]
+ *
+ * See SHRegCreateUSKeyA.
+ */
+LONG WINAPI SHRegCreateUSKeyW(LPCWSTR pszPath, REGSAM samDesired, HUSKEY hRelativeUSKey,
+ PHUSKEY phNewUSKey, DWORD dwFlags)
+{
+ FIXME("(%s, 0x%08lx, %p, %p, 0x%08lx) stub\n", debugstr_w(pszPath), samDesired,
+ hRelativeUSKey, phNewUSKey, dwFlags);
+ return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegDeleteEmptyUSKeyA [SHLWAPI.@]
+ *
+ * Delete an empty user-specific registry key.
+ *
+ * PARAMS
+ * hUSKey [I] Handle to an open registry key.
+ * pszValue [I] Empty key name.
+ * delRegFlags [I] Flag that specifies the base from which to delete
+ * the key.
+ *
+ * RETURNS
+ * Success: ERROR_SUCCESS
+ * Failure: Nonzero error code from winerror.h
+ */
+LONG WINAPI SHRegDeleteEmptyUSKeyA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
+{
+ FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
+ return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegDeleteEmptyUSKeyW [SHLWAPI.@]
+ *
+ * See SHRegDeleteEmptyUSKeyA.
+ */
+LONG WINAPI SHRegDeleteEmptyUSKeyW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
+{
+ FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
+ return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegDeleteUSValueA [SHLWAPI.@]
+ *
+ * Delete a user-specific registry value.
+ *
+ * PARAMS
+ * hUSKey [I] Handle to an open registry key.
+ * pszValue [I] Specifies the value to delete.
+ * delRegFlags [I] Flag that specifies the base of the key from which to
+ * delete the value.
+ *
+ * RETURNS
+ * Success: ERROR_SUCCESS
+ * Failure: Nonzero error code from winerror.h
+ */
+LONG WINAPI SHRegDeleteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
+{
+ FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
+ return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegDeleteUSValueW [SHLWAPI.@]
+ *
+ * See SHRegDeleteUSValueA.
+ */
+LONG WINAPI SHRegDeleteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
+{
+ FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
+ return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegEnumUSValueA [SHLWAPI.@]
+ *
+ * Enumerate values of a specified registry key.
+ *
+ * PARAMS
+ * hUSKey [I] Handle to an open registry key.
+ * dwIndex [I] Index of the value to be retrieved.
+ * pszValueName [O] Buffer to receive the value name.
+ * pcchValueNameLen [I] Size of pszValueName in characters.
+ * pdwType [O] Receives data type of the value.
+ * pvData [O] Receives value data. May be NULL.
+ * pcbData [I/O] Size of pvData in bytes.
+ * enumRegFlags [I] Flag that specifies the base key under which to
+ * enumerate values.
+ *
+ * RETURNS
+ * Success: ERROR_SUCCESS
+ * Failure: Nonzero error code from winerror.h
+ */
+LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName,
+ LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
+ LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
+{
+ FIXME("(%p, 0x%08lx, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex,
+ debugstr_a(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
+ return ERROR_INVALID_FUNCTION;
+}
+
+/*************************************************************************
+ * SHRegEnumUSValueW [SHLWAPI.@]
+ *
+ * See SHRegEnumUSValueA.
+ */
+LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName,
+ LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
+ LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
+{
+ FIXME("(%p, 0x%08lx, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex,
+ debugstr_w(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
+ return ERROR_INVALID_FUNCTION;
+}
+
/*************************************************************************
* SHRegQueryUSValueA [SHLWAPI.@]
*
LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType,
LPVOID pvData, DWORD cbData, DWORD dwFlags)
{
- LONG dummy;
+ DWORD dummy;
LPSHUSKEY hKey = (LPSHUSKEY)hUSKey;
LONG ret = ERROR_SUCCESS;
{
DWORD dwRet = ERROR_SUCCESS, dwDummy;
HKEY hSubKey;
- char szEmpty[] = "";
+ static const char szEmpty[] = { '\0' };
TRACE("(hkey=%p,%s,%s,%ld,%p,%ld)\n", hKey, debugstr_a(lpszSubKey),
debugstr_a(lpszValue), dwType, pvData, cbData);
if (lpszSubKey && *lpszSubKey)
- dwRet = RegCreateKeyExA(hKey, lpszSubKey, 0, szEmpty,
+ dwRet = RegCreateKeyExA(hKey, lpszSubKey, 0, (LPSTR)szEmpty,
0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy);
else
hSubKey = hKey;
{
DWORD dwRet = ERROR_SUCCESS, dwDummy;
HKEY hSubKey;
- WCHAR szEmpty[] = { '\0' };
+ static const WCHAR szEmpty[] = { '\0' };
TRACE("(hkey=%p,%s,%s,%ld,%p,%ld)\n", hKey, debugstr_w(lpszSubKey),
debugstr_w(lpszValue), dwType, pvData, cbData);
if (lpszSubKey && *lpszSubKey)
- dwRet = RegCreateKeyExW(hKey, lpszSubKey, 0, szEmpty,
+ dwRet = RegCreateKeyExW(hKey, lpszSubKey, 0, (LPWSTR)szEmpty,
0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy);
else
hSubKey = hKey;
*
* REG_EXPAND_SZ:
* case-1: the unexpanded string is smaller than the expanded one
- * subcase-1: the buffer is to small to hold the unexpanded string:
+ * subcase-1: the buffer is too small to hold the unexpanded string:
* function fails and returns the size of the unexpanded string.
*
- * subcase-2: buffer is to small to hold the expanded string:
+ * subcase-2: buffer is too small to hold the expanded string:
* the function return success (!!) and the result is truncated
- * *** This is clearly a error in the native implementation. ***
+ * *** This is clearly an error in the native implementation. ***
*
* case-2: the unexpanded string is bigger than the expanded one
* The buffer must have enough space to hold the unexpanded
/* Expand type REG_EXPAND_SZ into REG_SZ */
LPSTR szData;
- /* If the caller didn't supply a buffer or the buffer is to small we have
+ /* If the caller didn't supply a buffer or the buffer is too small we have
* to allocate our own
*/
if ((!pvData) || (dwRet == ERROR_MORE_DATA) )
char cNull = '\0';
nBytesToAlloc = (!pvData || (dwRet == ERROR_MORE_DATA)) ? dwUnExpDataLen : *pcbData;
- szData = (LPSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc);
+ szData = (LPSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
RegQueryValueExA (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
dwExpDataLen = ExpandEnvironmentStringsA(szData, &cNull, 1);
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
}
else
{
- nBytesToAlloc = lstrlenA(pvData) * sizeof (CHAR);
- szData = (LPSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc + 1);
+ nBytesToAlloc = (lstrlenA(pvData)+1) * sizeof (CHAR);
+ szData = (LPSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc );
lstrcpyA(szData, pvData);
dwExpDataLen = ExpandEnvironmentStringsA(szData, pvData, *pcbData / sizeof(CHAR));
if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
WCHAR cNull = '\0';
nBytesToAlloc = (!pvData || (dwRet == ERROR_MORE_DATA)) ? dwUnExpDataLen : *pcbData;
- szData = (LPWSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc);
+ szData = (LPWSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
RegQueryValueExW (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
dwExpDataLen = ExpandEnvironmentStringsW(szData, &cNull, 1);
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
}
else
{
- nBytesToAlloc = lstrlenW(pvData) * sizeof(WCHAR);
- szData = (LPWSTR) LocalAlloc(GMEM_ZEROINIT, nBytesToAlloc + 1);
+ nBytesToAlloc = (lstrlenW(pvData) + 1) * sizeof(WCHAR);
+ szData = (LPWSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc );
lstrcpyW(szData, pvData);
dwExpDataLen = ExpandEnvironmentStringsW(szData, pvData, *pcbData/sizeof(WCHAR) );
if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
*/
DWORD WINAPI SHDeleteKeyA(HKEY hKey, LPCSTR lpszSubKey)
{
- DWORD dwRet, dwKeyCount = 0, dwMaxSubkeyLen = 0, dwSize, i;
+ DWORD dwRet, dwMaxSubkeyLen = 0, dwSize;
CHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
HKEY hSubKey = 0;
dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
if(!dwRet)
{
- /* Find how many subkeys there are */
- dwRet = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
+ /* Find the maximum subkey length so that we can allocate a buffer */
+ dwRet = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, NULL,
&dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
if(!dwRet)
{
dwRet = ERROR_NOT_ENOUGH_MEMORY;
else
{
- /* Recursively delete all the subkeys */
- for(i = 0; i < dwKeyCount && !dwRet; i++)
+ while (dwRet == ERROR_SUCCESS)
{
dwSize = dwMaxSubkeyLen;
- dwRet = RegEnumKeyExA(hSubKey, i, lpszName, &dwSize, NULL, NULL, NULL, NULL);
- if(!dwRet)
+ dwRet = RegEnumKeyExA(hSubKey, 0, lpszName, &dwSize, NULL, NULL, NULL, NULL);
+ if (dwRet == ERROR_SUCCESS || dwRet == ERROR_MORE_DATA)
dwRet = SHDeleteKeyA(hSubKey, lpszName);
}
+ if (dwRet == ERROR_NO_MORE_ITEMS)
+ dwRet = ERROR_SUCCESS;
if (lpszName != szNameBuf)
HeapFree(GetProcessHeap(), 0, lpszName); /* Free buffer if allocated */
}
return FALSE;
}
+/*************************************************************************
+ * @ [SHLWAPI.330]
+ *
+ * Get the file extension for a given Mime type.
+ *
+ * PARAMS
+ * lpszType [I] Mime type to get the file extension for
+ * lpExt [O] Destination for the resulting extension
+ * iLen [I] Length of lpExt in characters
+ *
+ * RETURNS
+ * Success: TRUE. lpExt contains the file extension.
+ * Failure: FALSE, if any parameter is invalid or the extension cannot be
+ * retrieved. If iLen > 0, lpExt is set to an empty string.
+ *
+ * NOTES
+ * - The extension returned in lpExt always has a leading '.' character, even
+ * if the registry Mime database entry does not.
+ * - iLen must be long enough for the file extension for this function to succeed.
+ */
+BOOL WINAPI MIME_GetExtensionA(LPCSTR lpszType, LPSTR lpExt, INT iLen)
+{
+ char szSubKey[MAX_PATH];
+ DWORD dwlen = iLen - 1, dwType;
+ BOOL bRet = FALSE;
+
+ if (iLen > 0 && lpExt)
+ *lpExt = '\0';
+
+ if (lpszType && lpExt && iLen > 2 &&
+ GetMIMETypeSubKeyA(lpszType, szSubKey, MAX_PATH) &&
+ !SHGetValueA(HKEY_CLASSES_ROOT, szSubKey, szExtensionA, &dwType, lpExt + 1, &dwlen) &&
+ lpExt[1])
+ {
+ if (lpExt[1] == '.')
+ memmove(lpExt, lpExt + 1, strlen(lpExt + 1) + 1);
+ else
+ *lpExt = '.'; /* Supply a '.' */
+ bRet = TRUE;
+ }
+ return bRet;
+}
+
+/*************************************************************************
+ * @ [SHLWAPI.331]
+ *
+ * Unicode version of MIME_GetExtensionA.
+ */
+BOOL WINAPI MIME_GetExtensionW(LPCWSTR lpszType, LPWSTR lpExt, INT iLen)
+{
+ WCHAR szSubKey[MAX_PATH];
+ DWORD dwlen = iLen - 1, dwType;
+ BOOL bRet = FALSE;
+
+ if (iLen > 0 && lpExt)
+ *lpExt = '\0';
+
+ if (lpszType && lpExt && iLen > 2 &&
+ GetMIMETypeSubKeyW(lpszType, szSubKey, MAX_PATH) &&
+ !SHGetValueW(HKEY_CLASSES_ROOT, szSubKey, szExtensionW, &dwType, lpExt + 1, &dwlen) &&
+ lpExt[1])
+ {
+ if (lpExt[1] == '.')
+ memmove(lpExt, lpExt + 1, (strlenW(lpExt + 1) + 1) * sizeof(WCHAR));
+ else
+ *lpExt = '.'; /* Supply a '.' */
+ bRet = TRUE;
+ }
+ return bRet;
+}
+
/*************************************************************************
* @ [SHLWAPI.324]
*
* Copy a key and its values/sub keys to another location.
*
* PARAMS
- * hKeyDst [I] Destination key
- * lpszSubKey [I] Sub key under hKeyDst, or NULL to use hKeyDst directly
* hKeySrc [I] Source key to copy from
+ * lpszSrcSubKey [I] Sub key under hKeySrc, or NULL to use hKeySrc directly
+ * hKeyDst [I] Destination key
* dwReserved [I] Reserved, must be 0
*
* RETURNS
* (It will loop until out of stack, or the registry is full). This
* bug is present in Win32 also.
*/
-DWORD WINAPI SHCopyKeyA(HKEY hKeyDst, LPCSTR lpszSubKey, HKEY hKeySrc, DWORD dwReserved)
+DWORD WINAPI SHCopyKeyA(HKEY hKeySrc, LPCSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved)
{
WCHAR szSubKeyW[MAX_PATH];
- TRACE("(hkey=%p,%s,%p08x,%ld)\n", hKeyDst, debugstr_a(lpszSubKey), hKeySrc, dwReserved);
+ TRACE("(hkey=%p,%s,%p08x,%ld)\n", hKeySrc, debugstr_a(lpszSrcSubKey), hKeyDst, dwReserved);
- if (lpszSubKey)
- MultiByteToWideChar(0, 0, lpszSubKey, -1, szSubKeyW, MAX_PATH);
+ if (lpszSrcSubKey)
+ MultiByteToWideChar(0, 0, lpszSrcSubKey, -1, szSubKeyW, MAX_PATH);
- return SHCopyKeyW(hKeyDst, lpszSubKey ? szSubKeyW : NULL, hKeySrc, dwReserved);
+ return SHCopyKeyW(hKeySrc, lpszSrcSubKey ? szSubKeyW : NULL, hKeyDst, dwReserved);
}
/*************************************************************************
*
* See SHCopyKeyA.
*/
-DWORD WINAPI SHCopyKeyW(HKEY hKeyDst, LPCWSTR lpszSubKey, HKEY hKeySrc, DWORD dwReserved)
+DWORD WINAPI SHCopyKeyW(HKEY hKeySrc, LPCWSTR lpszSrcSubKey, HKEY hKeyDst, DWORD dwReserved)
{
DWORD dwKeyCount = 0, dwValueCount = 0, dwMaxKeyLen = 0;
DWORD dwMaxValueLen = 0, dwMaxDataLen = 0, i;
WCHAR szName[MAX_PATH], *lpszName = szName;
DWORD dwRet = S_OK;
- TRACE("hkey=%p,%s,%p08x,%ld)\n", hKeyDst, debugstr_w(lpszSubKey), hKeySrc, dwReserved);
+ TRACE("hkey=%p,%s,%p08x,%ld)\n", hKeySrc, debugstr_w(lpszSrcSubKey), hKeyDst, dwReserved);
if(!hKeyDst || !hKeySrc)
dwRet = ERROR_INVALID_PARAMETER;
else
{
- /* Open destination key */
- if(lpszSubKey)
- dwRet = RegOpenKeyExW(hKeyDst, lpszSubKey, 0, KEY_ALL_ACCESS, &hKeyDst);
+ /* Open source key */
+ if(lpszSrcSubKey)
+ dwRet = RegOpenKeyExW(hKeySrc, lpszSrcSubKey, 0, KEY_ALL_ACCESS, &hKeySrc);
if(dwRet)
- hKeyDst = 0; /* Don't close this key since we didn't open it */
+ hKeyDst = NULL; /* Don't close this key since we didn't open it */
else
{
/* Get details about sub keys and values */
if(!dwRet)
{
/* Recursively copy keys and values from the sub key */
- dwRet = SHCopyKeyW(hSubKeyDst, NULL, hSubKeySrc, 0);
+ dwRet = SHCopyKeyW(hSubKeySrc, NULL, hSubKeyDst, 0);
RegCloseKey(hSubKeyDst);
}
}
if (lpBuff != buff)
HeapFree(GetProcessHeap(), 0, lpBuff);
- if (lpszSubKey && hKeyDst)
+ if (lpszSrcSubKey && hKeyDst)
RegCloseKey(hKeyDst);
return dwRet;
}