Added an unknown VxD error code.
[wine] / dlls / shell32 / shlfileop.c
1 /*
2  * SHFileOperation
3  */
4 #include <string.h>
5 #include "debugtools.h"
6 #include "shellapi.h"
7 #include "shlwapi.h"
8
9 #include "shlobj.h"
10 #include "shresdef.h"
11 #include "shell32_main.h"
12 #include "wine/undocshell.h"
13 #include "shlwapi.h"
14
15 DEFAULT_DEBUG_CHANNEL(shell);
16
17 BOOL SHELL_WarnItemDelete (int nKindOfDialog, LPCSTR szDir)
18 {
19         char szCaption[255], szText[255], szBuffer[MAX_PATH + 256];
20
21         if(nKindOfDialog == ASK_DELETE_FILE)
22         {
23           LoadStringA(shell32_hInstance, IDS_DELETEITEM_TEXT, szText, 
24                 sizeof(szText));
25           LoadStringA(shell32_hInstance, IDS_DELETEITEM_CAPTION, 
26                 szCaption, sizeof(szCaption));
27         }
28         else if(nKindOfDialog == ASK_DELETE_FOLDER)
29         {
30           LoadStringA(shell32_hInstance, IDS_DELETEITEM_TEXT, szText, 
31                 sizeof(szText));
32           LoadStringA(shell32_hInstance, IDS_DELETEFOLDER_CAPTION, 
33                 szCaption, sizeof(szCaption));
34         }
35         else if(nKindOfDialog == ASK_DELETE_MULTIPLE_ITEM)
36         {
37           LoadStringA(shell32_hInstance, IDS_DELETEMULTIPLE_TEXT, szText, 
38                 sizeof(szText));
39           LoadStringA(shell32_hInstance, IDS_DELETEITEM_CAPTION, 
40                 szCaption, sizeof(szCaption));
41         }
42         else {
43           FIXME("Called without a valid nKindOfDialog specified!\n");
44           LoadStringA(shell32_hInstance, IDS_DELETEITEM_TEXT, szText, 
45                 sizeof(szText));
46           LoadStringA(shell32_hInstance, IDS_DELETEITEM_CAPTION, 
47                 szCaption, sizeof(szCaption));
48         }          
49
50         FormatMessageA(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
51             szText, 0, 0, szBuffer, sizeof(szBuffer), (va_list*)&szDir);
52
53         return (IDOK == MessageBoxA(GetActiveWindow(), szBuffer, szCaption, MB_OKCANCEL | MB_ICONEXCLAMATION));
54 }
55
56 /**************************************************************************
57  *      SHELL_DeleteDirectoryA()
58  *
59  * like rm -r
60  */
61
62 BOOL SHELL_DeleteDirectoryA(LPCSTR pszDir, BOOL bShowUI)
63 {
64         BOOL            ret = FALSE;
65         HANDLE          hFind;
66         WIN32_FIND_DATAA wfd;
67         char            szTemp[MAX_PATH];
68
69         strcpy(szTemp, pszDir);
70         PathAddBackslashA(szTemp);
71         strcat(szTemp, "*.*");
72         
73         if (bShowUI && !SHELL_WarnItemDelete(ASK_DELETE_FOLDER, pszDir))
74           return FALSE;
75         
76         if(INVALID_HANDLE_VALUE != (hFind = FindFirstFileA(szTemp, &wfd)))
77         {
78           do
79           {
80             if(strcasecmp(wfd.cFileName, ".") && strcasecmp(wfd.cFileName, ".."))
81             {
82               strcpy(szTemp, pszDir);
83               PathAddBackslashA(szTemp);
84               strcat(szTemp, wfd.cFileName);
85         
86               if(FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes)
87                 SHELL_DeleteDirectoryA(szTemp, FALSE);
88               else
89                 DeleteFileA(szTemp);
90             }
91           } while(FindNextFileA(hFind, &wfd));
92
93           FindClose(hFind);
94           ret = RemoveDirectoryA(pszDir);
95         }
96
97         return ret;
98 }
99
100 /**************************************************************************
101  *      SHELL_DeleteFileA()
102  */
103
104 BOOL SHELL_DeleteFileA(LPCSTR pszFile, BOOL bShowUI)
105 {
106         if (bShowUI && !SHELL_WarnItemDelete(ASK_DELETE_FILE, pszFile))
107                 return FALSE;
108  
109         return DeleteFileA(pszFile);
110 }
111
112 /*************************************************************************
113  * SHCreateDirectory                            [SHELL32.165]
114  *
115  * NOTES
116  *  exported by ordinal
117  *  not sure about LPSECURITY_ATTRIBUTES
118  */
119 DWORD WINAPI SHCreateDirectory(LPSECURITY_ATTRIBUTES sec,LPCSTR path)
120 {
121         DWORD ret;
122         TRACE("(%p,%s)\n",sec,path);
123         if ((ret = CreateDirectoryA(path,sec)))
124         {
125           SHChangeNotifyA(SHCNE_MKDIR, SHCNF_PATHA, path, NULL);
126         }
127         return ret;
128 }
129
130 /************************************************************************
131  *      Win32DeleteFile                         [SHELL32.164]  
132  *
133  * Deletes a file.  Also triggers a change notify if one exists.
134  *
135  * FIXME:
136  * Verified on Win98 / IE 5 (SHELL32 4.72, March 1999 build) to be
137  * ANSI.  Is this Unicode on NT?
138  *
139  */ 
140
141 BOOL WINAPI Win32DeleteFile(LPSTR fName)
142 {
143         TRACE("%p(%s)\n", fName, fName);
144
145         DeleteFileA(fName);
146         SHChangeNotifyA(SHCNE_DELETE, SHCNF_PATHA, fName, NULL);
147         return TRUE;
148 }
149
150 /*************************************************************************
151  * SHFileOperationA                             [SHELL32.243]
152  *
153  * NOTES
154  *     exported by name
155  */
156 DWORD WINAPI SHFileOperationA (LPSHFILEOPSTRUCTA lpFileOp)   
157 {
158         LPSTR pFrom = (LPSTR)lpFileOp->pFrom;
159         LPSTR pTo = (LPSTR)lpFileOp->pTo;
160         LPSTR pTempTo;
161         
162         switch(lpFileOp->wFunc) {
163         case FO_COPY:
164                 TRACE("File Copy:\n");
165                 while(1) {
166                         if(!pFrom[0]) break;
167                         if(!pTo[0]) break;
168                         TRACE("   From='%s' To='%s'\n", pFrom, pTo);
169
170                         pTempTo = HeapAlloc(GetProcessHeap(), 0, strlen(pTo)+1);
171                         if (pTempTo)
172                         {
173                             strcpy( pTempTo, pTo );
174                             PathRemoveFileSpecA(pTempTo);
175                             TRACE("   Creating Directory '%s'\n", pTempTo);
176                             SHCreateDirectory(NULL,pTempTo);
177                             HeapFree(GetProcessHeap(), 0, pTempTo);
178                         }
179                         CopyFileA(pFrom, pTo, FALSE);
180
181                         pFrom += strlen(pFrom) + 1;
182                         pTo += strlen(pTo) + 1;
183                 }
184                 TRACE("Setting AnyOpsAborted=FALSE\n");
185                 lpFileOp->fAnyOperationsAborted=FALSE;
186                 return 0;
187
188         case FO_DELETE:
189                 TRACE("File Delete:\n");
190                 while(1) {
191                         if(!pFrom[0]) break;
192                         TRACE("   File='%s'\n", pFrom);
193                         DeleteFileA(pFrom);
194                         pFrom += strlen(pFrom) + 1;
195                 }
196                 TRACE("Setting AnyOpsAborted=FALSE\n");
197                 lpFileOp->fAnyOperationsAborted=FALSE;
198                 return 0;
199
200         default:
201                 FIXME("Unhandled shell file operation %d\n", lpFileOp->wFunc);
202         }
203
204         return 1;
205 }
206
207 /*************************************************************************
208  * SHFileOperationW                             [SHELL32.244]
209  *
210  * NOTES
211  *     exported by name
212  */
213 DWORD WINAPI SHFileOperationW (LPSHFILEOPSTRUCTW lpFileOp)   
214 {
215         FIXME("(%p):stub.\n", lpFileOp);
216         return 1;
217 }
218
219 /*************************************************************************
220  * SHFileOperation                              [SHELL32.242]
221  *
222  */
223 DWORD WINAPI SHFileOperationAW(LPVOID lpFileOp)
224 {
225         if (SHELL_OsIsUnicode())
226           return SHFileOperationW(lpFileOp);
227         return SHFileOperationA(lpFileOp);
228 }
229
230 /*************************************************************************
231  * SheGetDirW [SHELL32.281]
232  *
233  */
234 HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
235 {       FIXME("%p %p stub\n",u,v);
236         return 0;
237 }
238
239 /*************************************************************************
240  * SheChangeDirW [SHELL32.274]
241  *
242  */
243 HRESULT WINAPI SheChangeDirW(LPWSTR u)
244 {       FIXME("(%s),stub\n",debugstr_w(u));
245         return 0;
246 }
247
248 /*************************************************************************
249  * IsNetDrive                   [SHELL32.66]
250  */
251 BOOL WINAPI IsNetDrive(DWORD drive)
252 {
253         char root[4];
254         strcpy(root, "A:\\");
255         root[0] += drive;
256         return (GetDriveTypeA(root) == DRIVE_REMOTE);
257 }