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; } /**************************************************************************