shell32: some new functions in shlfileop
Rolf Kalbermatter
rolf.kalbermatter at citeng.com
Fri Mar 21 04:09:28 CST 2003
Changelog
* dlls/shell32/shell32.spec
Implement some more Win API functions.
* dlls/shell32/shlfileop.c
Implement some more Win API functions and add support functions for coming changes
to SHFileOperation.
Rolf Kalbermatter
License: X11, LGPL
Index: dlls/shell32/shell32.spec
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shell32.spec,v
retrieving revision 1.65
diff -u -r1.65 shell32.spec
--- dlls/shell32/shell32.spec 20 Mar 2003 03:53:13 -0000 1.65
+++ dlls/shell32/shell32.spec 21 Mar 2003 09:02:10 -0000
@@ -84,8 +84,8 @@
90 stub SHFindFiles
91 stub SHFindComputer
92 stdcall PathGetShortPath (ptr) PathGetShortPathAW
- 93 stub Win32CreateDirectory
- 94 stub Win32RemoveDirectory
+ 93 stdcall Win32CreateDirectory (wstr, ptr) Win32CreateDirectoryAW
+ 94 stdcall Win32RemoveDirectory (wstr) Win32RemoveDirectoryAW
95 stdcall SHLogILFromFSIL (ptr)
96 stdcall StrRetToStrN (ptr long ptr ptr) StrRetToStrNAW
97 stdcall SHWaitForFileToOpen (long long long)
@@ -410,6 +410,9 @@
# version 5.00 (Win2K)
# _WIN32_IE >= 0x0500
#
+@ forward SHGetDiskFreeSpaceA kernel32.GetDiskFreeSpaceExA
+@ stdcall SHGetDiskFreeSpaceExA kernel32.GetDiskFreeSpaceExA
+@ stdcall SHGetDiskFreeSpaceExW kernel32.GetDiskFreeSpaceExW
@ stdcall SHGetFolderPathA(long long long long ptr)
@ stdcall SHGetFolderPathW(long long long long ptr)
@ stdcall SHGetFolderLocation(long long long long ptr)
Index: dlls/shell32/shlfileop.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shlfileop.c,v
retrieving revision 1.25
diff -u -r1.25 shlfileop.c
--- dlls/shell32/shlfileop.c 18 Mar 2003 18:35:49 -0000 1.25
+++ dlls/shell32/shlfileop.c 21 Mar 2003 09:59:53 -0000
@@ -23,6 +23,7 @@
#include "wine/port.h"
#include <string.h>
+#include <ctype.h>
#include "winreg.h"
#include "shellapi.h"
@@ -35,177 +36,505 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-BOOL SHELL_ConfirmDialog (int nKindOfDialog, LPCSTR szDir)
+#define IsAttribFile(x) (!(x == -1) && !(x & FILE_ATTRIBUTE_DIRECTORY))
+#define IsAttribDir(x) (!(x == -1) && (x & FILE_ATTRIBUTE_DIRECTORY))
+
+#define IsDotDir(x) ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
+
+CHAR aWildcardFile[] = {'*','.','*',0};
+WCHAR wWildcardFile[] = {'*','.','*',0};
+WCHAR wWildcardChars[] = {'*','?',0};
+WCHAR wBackslash[] = {'\\',0};
+
+static BOOL SHNotifyCreateDirectoryA(LPCSTR path, LPSECURITY_ATTRIBUTES sec);
+static BOOL SHNotifyCreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec);
+static BOOL SHNotifyRemoveDirectoryA(LPCSTR path);
+static BOOL SHNotifyRemoveDirectoryW(LPCWSTR path);
+static BOOL SHNotifyDeleteFileA(LPCSTR path);
+static BOOL SHNotifyDeleteFileW(LPCWSTR path);
+static BOOL SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest);
+static BOOL SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bRenameIfExists);
+
+typedef struct
{
- char szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
UINT caption_resource_id, text_resource_id;
+} SHELL_ConfirmIDstruc;
- switch(nKindOfDialog) {
+static BOOL SHELL_ConfirmIDs(int nKindOfDialog, SHELL_ConfirmIDstruc *ids)
+{
+ switch (nKindOfDialog) {
+ case ASK_DELETE_FILE:
+ ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
+ ids->text_resource_id = IDS_DELETEITEM_TEXT;
+ return TRUE;
+ case ASK_DELETE_FOLDER:
+ ids->caption_resource_id = IDS_DELETEFOLDER_CAPTION;
+ ids->text_resource_id = IDS_DELETEITEM_TEXT;
+ return TRUE;
+ case ASK_DELETE_MULTIPLE_ITEM:
+ ids->caption_resource_id = IDS_DELETEITEM_CAPTION;
+ ids->text_resource_id = IDS_DELETEMULTIPLE_TEXT;
+ return TRUE;
+ case ASK_OVERWRITE_FILE:
+ ids->caption_resource_id = IDS_OVERWRITEFILE_CAPTION;
+ ids->text_resource_id = IDS_OVERWRITEFILE_TEXT;
+ return TRUE;
+ default:
+ FIXME(" Unhandled nKindOfDialog %d stub\n", nKindOfDialog);
+ }
+ return FALSE;
+}
- case ASK_DELETE_FILE:
- caption_resource_id = IDS_DELETEITEM_CAPTION;
- text_resource_id = IDS_DELETEITEM_TEXT;
- break;
- case ASK_DELETE_FOLDER:
- caption_resource_id = IDS_DELETEFOLDER_CAPTION;
- text_resource_id = IDS_DELETEITEM_TEXT;
- break;
- case ASK_DELETE_MULTIPLE_ITEM:
- caption_resource_id = IDS_DELETEITEM_CAPTION;
- text_resource_id = IDS_DELETEMULTIPLE_TEXT;
- break;
- case ASK_OVERWRITE_FILE:
- caption_resource_id = IDS_OVERWRITEFILE_CAPTION;
- text_resource_id = IDS_OVERWRITEFILE_TEXT;
- break;
- default:
- FIXME(" Unhandled nKindOfDialog %d stub\n", nKindOfDialog);
+BOOL SHELL_ConfirmDialog(int nKindOfDialog, LPCSTR szDir)
+{
+ CHAR szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
+ SHELL_ConfirmIDstruc ids;
+
+ if (!SHELL_ConfirmIDs(nKindOfDialog, &ids))
return FALSE;
- }
- LoadStringA(shell32_hInstance, caption_resource_id, szCaption, sizeof(szCaption));
- LoadStringA(shell32_hInstance, text_resource_id, szText, sizeof(szText));
+ LoadStringA(shell32_hInstance, ids.caption_resource_id, szCaption, sizeof(szCaption));
+ LoadStringA(shell32_hInstance, ids.text_resource_id, szText, sizeof(szText));
- FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ FormatMessageA(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)&szDir);
return (IDOK == MessageBoxA(GetActiveWindow(), szBuffer, szCaption, MB_OKCANCEL | MB_ICONEXCLAMATION));
}
+BOOL SHELL_ConfirmDialogW(int nKindOfDialog, LPCWSTR szDir)
+{
+ WCHAR szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
+ SHELL_ConfirmIDstruc ids;
+
+ if (!SHELL_ConfirmIDs(nKindOfDialog, &ids))
+ return FALSE;
+
+ LoadStringW(shell32_hInstance, ids.caption_resource_id, szCaption, sizeof(szCaption));
+ LoadStringW(shell32_hInstance, ids.text_resource_id, szText, sizeof(szText));
+
+ FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)&szDir);
+
+ return (IDOK == MessageBoxW(GetActiveWindow(), szBuffer, szCaption, MB_OKCANCEL | MB_ICONEXCLAMATION));
+}
+
/**************************************************************************
- * SHELL_DeleteDirectoryA()
+ * SHELL_DeleteDirectoryA() [internal]
*
* like rm -r
*/
-
BOOL SHELL_DeleteDirectoryA(LPCSTR pszDir, BOOL bShowUI)
{
- BOOL ret = FALSE;
- HANDLE hFind;
+ BOOL ret = TRUE;
+ HANDLE hFind;
WIN32_FIND_DATAA wfd;
- char szTemp[MAX_PATH];
-
- strcpy(szTemp, pszDir);
- PathAddBackslashA(szTemp);
- strcat(szTemp, "*.*");
+ char szTemp[MAX_PATH];
- if (bShowUI && !SHELL_ConfirmDialog(ASK_DELETE_FOLDER, pszDir))
+ /* Make sure the directory exists before eventually prompting the user */
+ PathCombineA(szTemp, pszDir, aWildcardFile);
+ hFind = FindFirstFileA(szTemp, &wfd);
+ if (hFind == INVALID_HANDLE_VALUE)
return FALSE;
- if(INVALID_HANDLE_VALUE != (hFind = FindFirstFileA(szTemp, &wfd)))
+ if (!bShowUI || SHELL_ConfirmDialog(ASK_DELETE_FOLDER, pszDir))
{
do
{
- if(strcasecmp(wfd.cFileName, ".") && strcasecmp(wfd.cFileName, ".."))
- {
- strcpy(szTemp, pszDir);
- PathAddBackslashA(szTemp);
- strcat(szTemp, wfd.cFileName);
-
- if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
- SHELL_DeleteDirectoryA(szTemp, FALSE);
- else
- DeleteFileA(szTemp);
- }
- } while(FindNextFileA(hFind, &wfd));
-
- FindClose(hFind);
- ret = RemoveDirectoryA(pszDir);
+ LPSTR lp = wfd.cAlternateFileName;
+ if (!lp[0])
+ lp = wfd.cFileName;
+ if (IsDotDir(lp))
+ continue;
+ PathCombineA(szTemp, pszDir, lp);
+ if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
+ ret = SHELL_DeleteDirectoryA(szTemp, FALSE);
+ else
+ ret = SHNotifyDeleteFileA(szTemp);
+ } while (ret && FindNextFileA(hFind, &wfd));
}
+ FindClose(hFind);
+ if (ret)
+ ret = SHNotifyRemoveDirectoryA(pszDir);
+ return ret;
+}
+
+BOOL SHELL_DeleteDirectoryW(LPCWSTR pszDir, BOOL bShowUI)
+{
+ BOOL ret = TRUE;
+ HANDLE hFind;
+ WIN32_FIND_DATAW wfd;
+ WCHAR szTemp[MAX_PATH];
+
+ /* Make sure the directory exists before eventually prompting the user */
+ PathCombineW(szTemp, pszDir, wWildcardFile);
+ hFind = FindFirstFileW(szTemp, &wfd);
+ if (hFind == INVALID_HANDLE_VALUE)
+ return FALSE;
+ if (!bShowUI || SHELL_ConfirmDialogW(ASK_DELETE_FOLDER, pszDir))
+ {
+ do
+ {
+ LPWSTR lp = wfd.cAlternateFileName;
+ if (!lp[0])
+ lp = wfd.cFileName;
+ if (IsDotDir(lp))
+ continue;
+ PathCombineW(szTemp, pszDir, lp);
+ if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
+ ret = SHELL_DeleteDirectoryW(szTemp, FALSE);
+ else
+ ret = SHNotifyDeleteFileW(szTemp);
+ } while (ret && FindNextFileW(hFind, &wfd));
+ }
+ FindClose(hFind);
+ if (ret)
+ ret = SHNotifyRemoveDirectoryW(pszDir);
return ret;
}
/**************************************************************************
- * SHELL_DeleteFileA()
+ * SHELL_DeleteFileA() [internal]
*/
-
BOOL SHELL_DeleteFileA(LPCSTR pszFile, BOOL bShowUI)
{
if (bShowUI && !SHELL_ConfirmDialog(ASK_DELETE_FILE, pszFile))
- return FALSE;
+ return FALSE;
- return DeleteFileA(pszFile);
+ return SHNotifyDeleteFileA(pszFile);
}
-/*************************************************************************
- * SHCreateDirectory [SHELL32.165]
+BOOL SHELL_DeleteFileW(LPCWSTR pszFile, BOOL bShowUI)
+{
+ if (bShowUI && !SHELL_ConfirmDialogW(ASK_DELETE_FILE, pszFile))
+ return FALSE;
+
+ return SHNotifyDeleteFileW(pszFile);
+}
+
+/**************************************************************************
+ * Win32CreateDirectory [SHELL32.93]
*
- * NOTES
- * exported by ordinal
- * WinNT/2000 exports Unicode
+ * Creates a directory. Also triggers a change notify if one exists.
+ *
+ * PARAMS
+ * path [I] path to directory to create
+ *
+ * RETURNS
+ * TRUE if successful, FALSE otherwise
+ *
+ * NOTES:
+ * Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
+ * This is Unicode on NT/2000
*/
-DWORD WINAPI SHCreateDirectory(HWND hWnd, LPCVOID path)
+
+static BOOL SHNotifyCreateDirectoryA(LPCSTR path, LPSECURITY_ATTRIBUTES sec)
+{
+ BOOL ret;
+ TRACE("(%s, %p)\n", debugstr_a(path), sec);
+
+ ret = CreateDirectoryA(path, sec);
+ if (ret)
+ {
+ SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHA, path, NULL);
+ }
+ return ret;
+}
+
+static BOOL SHNotifyCreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
+{
+ BOOL ret;
+ TRACE("(%s, %p)\n", debugstr_w(path), sec);
+
+ ret = CreateDirectoryW(path, sec);
+ if (ret)
+ {
+ SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW, path, NULL);
+ }
+ return ret;
+}
+
+BOOL WINAPI Win32CreateDirectoryAW(LPCVOID path, LPSECURITY_ATTRIBUTES sec)
{
if (SHELL_OsIsUnicode())
- return SHCreateDirectoryExW(hWnd, path, NULL);
- return SHCreateDirectoryExA(hWnd, path, NULL);
+ return SHNotifyCreateDirectoryW(path, sec);
+ return SHNotifyCreateDirectoryA(path, sec);
}
-/*************************************************************************
- * SHCreateDirectoryExA [SHELL32.@]
+/************************************************************************
+ * Win32RemoveDirectory [SHELL32.94]
+ *
+ * Deletes a directory. Also triggers a change notify if one exists.
+ *
+ * PARAMS
+ * path [I] path to directory to delete
+ *
+ * RETURNS
+ * TRUE if successful, FALSE otherwise
+ *
+ * NOTES:
+ * Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
+ * This is Unicode on NT/2000
*/
-DWORD WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES sec)
+static BOOL SHNotifyRemoveDirectoryA(LPCSTR path)
{
- DWORD ret;
- TRACE("(%p, %s, %p)\n",hWnd, path, sec);
- if ((ret = CreateDirectoryA(path, sec)))
+ BOOL ret;
+ TRACE("(%s)\n", debugstr_a(path));
+
+ ret = RemoveDirectoryA(path);
+ if (!ret)
{
- SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHA, path, NULL);
+ /* Directory may be write protected */
+ DWORD dwAttr = GetFileAttributesA(path);
+ if (dwAttr != -1 && dwAttr & FILE_ATTRIBUTE_READONLY)
+ if (SetFileAttributesA(path, dwAttr & ~FILE_ATTRIBUTE_READONLY))
+ ret = RemoveDirectoryA(path);
}
- else if (hWnd)
- FIXME("Semi-stub, non zero hWnd should be used as parent for error dialog!");
+ if (ret)
+ SHChangeNotify(SHCNE_RMDIR, SHCNF_PATHA, path, NULL);
return ret;
}
-/*************************************************************************
- * SHCreateDirectoryExW [SHELL32.@]
- */
-DWORD WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
+static BOOL SHNotifyRemoveDirectoryW(LPCWSTR path)
{
- DWORD ret;
- TRACE("(%p, %s, %p)\n",hWnd, debugstr_w(path), sec);
- if ((ret = CreateDirectoryW(path, sec)))
+ BOOL ret;
+ TRACE("(%s)\n", debugstr_w(path));
+
+ ret = RemoveDirectoryW(path);
+ if (!ret)
{
- SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW, path, NULL);
+ /* Directory may be write protected */
+ DWORD dwAttr = GetFileAttributesW(path);
+ if (dwAttr != -1 && dwAttr & FILE_ATTRIBUTE_READONLY)
+ if (SetFileAttributesW(path, dwAttr & ~FILE_ATTRIBUTE_READONLY))
+ ret = RemoveDirectoryW(path);
}
- else if (hWnd)
- FIXME("Semi-stub, non zero hWnd should be used as parent for error dialog!");
+ if (ret)
+ SHChangeNotify(SHCNE_RMDIR, SHCNF_PATHW, path, NULL);
return ret;
}
+BOOL WINAPI Win32RemoveDirectoryAW(LPCVOID path)
+{
+ if (SHELL_OsIsUnicode())
+ return SHNotifyRemoveDirectoryW(path);
+ return SHNotifyRemoveDirectoryA(path);
+}
+
/************************************************************************
- * Win32DeleteFile [SHELL32.164]
+ * Win32DeleteFile [SHELL32.164]
*
* Deletes a file. Also triggers a change notify if one exists.
*
- * NOTES
+ * PARAMS
+ * path [I] path to file to delete
+ *
+ * RETURNS
+ * TRUE if successful, FALSE otherwise
+ *
+ * NOTES:
* Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be ANSI.
* This is Unicode on NT/2000
*/
-static BOOL Win32DeleteFileA(LPCSTR fName)
+static BOOL SHNotifyDeleteFileA(LPCSTR path)
{
- TRACE("%p(%s)\n", fName, fName);
+ BOOL ret;
+
+ TRACE("(%s)\n", debugstr_a(path));
- DeleteFileA(fName);
- SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, fName, NULL);
- return TRUE;
+ ret = DeleteFileA(path);
+ if (!ret)
+ {
+ /* File may be write protected or a system file */
+ DWORD dwAttr = GetFileAttributesA(path);
+ if ((dwAttr != -1) && (dwAttr & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
+ if (SetFileAttributesA(path, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
+ ret = DeleteFileA(path);
+ }
+ if (ret)
+ SHChangeNotify(SHCNE_DELETE, SHCNF_PATHA, path, NULL);
+ return ret;
}
-static BOOL Win32DeleteFileW(LPCWSTR fName)
+static BOOL SHNotifyDeleteFileW(LPCWSTR path)
{
- TRACE("%p(%s)\n", fName, debugstr_w(fName));
+ BOOL ret;
+
+ TRACE("(%s)\n", debugstr_w(path));
- DeleteFileW(fName);
- SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW, fName, NULL);
- return TRUE;
+ ret = DeleteFileW(path);
+ if (!ret)
+ {
+ /* File may be write protected or a system file */
+ DWORD dwAttr = GetFileAttributesW(path);
+ if ((dwAttr != -1) && (dwAttr & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
+ if (SetFileAttributesW(path, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
+ ret = DeleteFileW(path);
+ }
+ if (ret)
+ SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW, path, NULL);
+ return ret;
}
-DWORD WINAPI Win32DeleteFileAW(LPCVOID fName)
+DWORD WINAPI Win32DeleteFileAW(LPCVOID path)
{
if (SHELL_OsIsUnicode())
- return Win32DeleteFileW(fName);
- return Win32DeleteFileA(fName);
+ return SHNotifyDeleteFileW(path);
+ return SHNotifyDeleteFileA(path);
+}
+
+/************************************************************************
+ * SHNotifyMoveFile [internal]
+ *
+ * Moves a file. Also triggers a change notify if one exists.
+ *
+ * PARAMS
+ * src [I] path to source file to move
+ * dest [I] path to target file to move to
+ *
+ * RETURNS
+ * TRUE if successful, FALSE otherwise
+ */
+static BOOL SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest)
+{
+ BOOL ret;
+
+ TRACE("(%s %s)\n", debugstr_w(src), debugstr_w(dest));
+
+ ret = MoveFileW(src, dest);
+ if (!ret)
+ {
+ /* Source file may be write protected or a system file */
+ DWORD dwAttr = GetFileAttributesW(src);
+ if ((dwAttr != -1) && (dwAttr & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
+ if (SetFileAttributesW(src, dwAttr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM)))
+ ret = MoveFileW(src, dest);
+ }
+ if (ret)
+ SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATHW, src, dest);
+ return ret;
+}
+
+/************************************************************************
+ * SHNotifyCopyFile [internal]
+ *
+ * Copies a file. Also triggers a change notify if one exists.
+ *
+ * PARAMS
+ * src [I] path to source file to move
+ * dest [I] path to target file to move to
+ * bRename [I] if TRUE, the target file will be renamed if a
+ * file with this name already exists
+ *
+ * RETURNS
+ * TRUE if successful, FALSE otherwise
+ */
+static BOOL SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bRename)
+{
+ BOOL ret;
+
+ TRACE("(%s %s %s)\n", debugstr_w(src), debugstr_w(dest), bRename ? "renameIfExists" : "");
+
+ ret = CopyFileW(src, dest, TRUE);
+ if (!ret && bRename)
+ {
+ /* Destination file probably exists */
+ DWORD dwAttr = GetFileAttributesW(dest);
+ if (dwAttr != -1)
+ {
+ FIXME("Rename on copy to existing file not implemented!");
+ }
+ }
+ if (ret)
+ SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, dest, NULL);
+ return ret;
+}
+
+/*************************************************************************
+ * SHCreateDirectory [SHELL32.165]
+ *
+ * Create a directory at the specified location
+ *
+ * PARAMS
+ * hWnd [I]
+ * path [I] path of directory to create
+ *
+ * RETURNS
+ * ERRROR_SUCCESS or one of the following values:
+ * ERROR_BAD_PATHNAME if the path is relative
+ * ERROR_FILE_EXISTS when a file with that name exists
+ * ERROR_ALREADY_EXISTS when the directory already exists
+ * ERROR_FILENAME_EXCED_RANGE if the filename was to long to process
+ *
+ * NOTES
+ * exported by ordinal
+ * Win9x exports ANSI
+ * WinNT/2000 exports Unicode
+ */
+DWORD WINAPI SHCreateDirectory(HWND hWnd, LPCVOID path)
+{
+ if (SHELL_OsIsUnicode())
+ return SHCreateDirectoryExW(hWnd, path, NULL);
+ return SHCreateDirectoryExA(hWnd, path, NULL);
+}
+
+/*************************************************************************
+ * SHCreateDirectoryExA [SHELL32.@]
+ *
+ * Create a directory at the specified location
+ *
+ * PARAMS
+ * hWnd [I]
+ * path [I] path of directory to create
+ * sec [I] security attributes to use or NULL
+ *
+ * RETURNS
+ * ERRROR_SUCCESS or one of the following values:
+ * ERROR_BAD_PATHNAME if the path is relative
+ * ERROR_FILE_EXISTS when a file with that name exists
+ * ERROR_ALREADY_EXISTS when the directory already exists
+ * ERROR_FILENAME_EXCED_RANGE if the filename was to long to process
+ */
+DWORD WINAPI SHCreateDirectoryExA(HWND hWnd, LPCSTR path, LPSECURITY_ATTRIBUTES sec)
+{
+ WCHAR wPath[MAX_PATH];
+ TRACE("(%p, %s, %p)\n",hWnd, debugstr_a(path), sec);
+
+ MultiByteToWideChar(CP_ACP, 0, path, -1, wPath, MAX_PATH);
+ return SHCreateDirectoryExW(hWnd, wPath, sec);
+}
+
+/*************************************************************************
+ * SHCreateDirectoryExW [SHELL32.@]
+ */
+DWORD WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
+{
+ DWORD ret = ERROR_SUCCESS;
+ TRACE("(%p, %s, %p)\n",hWnd, debugstr_w(path), sec);
+
+ if (PathIsRelativeW(path))
+ {
+ ret = ERROR_BAD_PATHNAME;
+ SetLastError(ERROR_BAD_PATHNAME);
+ }
+ else
+ {
+ if (!SHNotifyCreateDirectoryW(path, sec))
+ {
+ ret = GetLastError();
+ if (ret != ERROR_FILE_EXISTS &&
+ ret != ERROR_ALREADY_EXISTS &&
+ ret != ERROR_FILENAME_EXCED_RANGE)
+ {
+ /* handling network file names?
+ lstrcpynW(pathName, path, MAX_PATH);
+ lpStr = PathAddBackslashW(pathName);*/
+ FIXME("Semi-stub, non zero hWnd should be used somehow?");
+ }
+ }
+ }
+ return ret;
}
/**************************************************************************
More information about the wine-patches
mailing list