1cc1a8c2cd40d1c307c0cb787b9d39f6deb88275
[reactos.git] / reactos / dll / win32 / userenv / desktop.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS system libraries
22 * FILE: lib/userenv/desktop.c
23 * PURPOSE: Desktop and start menu support functions.
24 * PROGRAMMER: Eric Kohl
25 */
26
27 #include "precomp.h"
28
29 #define NDEBUG
30 #include <debug.h>
31
32
33 /* FUNCTIONS ***************************************************************/
34
35 static BOOL
36 GetDesktopPath (BOOL bCommonPath,
37 LPWSTR lpDesktopPath)
38 {
39 WCHAR szPath[MAX_PATH];
40 DWORD dwLength;
41 DWORD dwType;
42 HKEY hKey;
43 LONG Error;
44
45 DPRINT ("GetDesktopPath() called\n");
46
47 Error = RegOpenKeyExW (HKEY_CURRENT_USER,
48 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
49 0,
50 KEY_QUERY_VALUE,
51 &hKey);
52 if (Error != ERROR_SUCCESS)
53 {
54 DPRINT1 ("RegOpenKeyExW() failed\n");
55 SetLastError((DWORD)Error);
56 return FALSE;
57 }
58
59 dwLength = MAX_PATH * sizeof(WCHAR);
60 Error = RegQueryValueExW (hKey,
61 bCommonPath ? L"Common Desktop" : L"Desktop",
62 0,
63 &dwType,
64 (LPBYTE)szPath,
65 &dwLength);
66 if (Error != ERROR_SUCCESS)
67 {
68 DPRINT1 ("RegQueryValueExW() failed\n");
69 RegCloseKey (hKey);
70 SetLastError((DWORD)Error);
71 return FALSE;
72 }
73
74 RegCloseKey (hKey);
75
76 if (dwType == REG_EXPAND_SZ)
77 {
78 ExpandEnvironmentStringsW (szPath,
79 lpDesktopPath,
80 MAX_PATH);
81 }
82 else
83 {
84 wcscpy (lpDesktopPath, szPath);
85 }
86
87 DPRINT ("GetDesktopPath() done\n");
88
89 return TRUE;
90 }
91
92
93 static BOOL
94 GetProgramsPath (BOOL bCommonPath,
95 LPWSTR lpProgramsPath)
96 {
97 WCHAR szPath[MAX_PATH];
98 DWORD dwLength;
99 DWORD dwType;
100 HKEY hKey;
101 LONG Error;
102
103 DPRINT ("GetProgramsPath() called\n");
104
105 Error = RegOpenKeyExW (HKEY_CURRENT_USER,
106 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
107 0,
108 KEY_QUERY_VALUE,
109 &hKey);
110 if (Error != ERROR_SUCCESS)
111 {
112 DPRINT1 ("RegOpenKeyExW() failed\n");
113 SetLastError((DWORD)Error);
114 return FALSE;
115 }
116
117 dwLength = MAX_PATH * sizeof(WCHAR);
118 Error = RegQueryValueExW (hKey,
119 bCommonPath ? L"Common Programs" : L"Programs",
120 0,
121 &dwType,
122 (LPBYTE)szPath,
123 &dwLength);
124 if (Error != ERROR_SUCCESS)
125 {
126 DPRINT1 ("RegQueryValueExW() failed\n");
127 RegCloseKey (hKey);
128 SetLastError((DWORD)Error);
129 return FALSE;
130 }
131
132 RegCloseKey (hKey);
133
134 if (dwType == REG_EXPAND_SZ)
135 {
136 ExpandEnvironmentStringsW (szPath,
137 lpProgramsPath,
138 MAX_PATH);
139 }
140 else
141 {
142 wcscpy (lpProgramsPath,
143 szPath);
144 }
145
146 DPRINT ("GetProgramsPath() done\n");
147
148 return TRUE;
149 }
150
151
152 BOOL WINAPI
153 AddDesktopItemA (BOOL bCommonItem,
154 LPCSTR lpItemName,
155 LPCSTR lpArguments,
156 LPCSTR lpIconLocation,
157 INT iIcon,
158 LPCSTR lpWorkingDirectory, /* Optional */
159 WORD wHotKey,
160 INT iShowCmd)
161 {
162 UNICODE_STRING ItemName;
163 UNICODE_STRING Arguments;
164 UNICODE_STRING IconLocation;
165 UNICODE_STRING WorkingDirectory;
166 BOOL bResult;
167 NTSTATUS Status;
168
169 Status = RtlCreateUnicodeStringFromAsciiz(&ItemName,
170 (LPSTR)lpItemName);
171 if (!NT_SUCCESS(Status))
172 {
173 SetLastError (RtlNtStatusToDosError (Status));
174 return FALSE;
175 }
176
177 Status = RtlCreateUnicodeStringFromAsciiz(&Arguments,
178 (LPSTR)lpArguments);
179 if (!NT_SUCCESS(Status))
180 {
181 RtlFreeUnicodeString(&ItemName);
182 SetLastError (RtlNtStatusToDosError (Status));
183 return FALSE;
184 }
185
186 Status = RtlCreateUnicodeStringFromAsciiz(&IconLocation,
187 (LPSTR)lpIconLocation);
188 if (!NT_SUCCESS(Status))
189 {
190 RtlFreeUnicodeString(&Arguments);
191 RtlFreeUnicodeString(&ItemName);
192 SetLastError (RtlNtStatusToDosError (Status));
193 return FALSE;
194 }
195
196 if (lpWorkingDirectory != NULL)
197 {
198 Status = RtlCreateUnicodeStringFromAsciiz(&WorkingDirectory,
199 (LPSTR)lpWorkingDirectory);
200 if (!NT_SUCCESS(Status))
201 {
202 RtlFreeUnicodeString(&IconLocation);
203 RtlFreeUnicodeString(&Arguments);
204 RtlFreeUnicodeString(&ItemName);
205 SetLastError (RtlNtStatusToDosError (Status));
206 return FALSE;
207 }
208 }
209
210 bResult = AddDesktopItemW(bCommonItem,
211 ItemName.Buffer,
212 Arguments.Buffer,
213 IconLocation.Buffer,
214 iIcon,
215 (lpWorkingDirectory != NULL) ? WorkingDirectory.Buffer : NULL,
216 wHotKey,
217 iShowCmd);
218
219 if (lpWorkingDirectory != NULL)
220 {
221 RtlFreeUnicodeString(&WorkingDirectory);
222 }
223
224 RtlFreeUnicodeString(&IconLocation);
225 RtlFreeUnicodeString(&Arguments);
226 RtlFreeUnicodeString(&ItemName);
227
228 return bResult;
229 }
230
231
232 BOOL WINAPI
233 AddDesktopItemW (BOOL bCommonDesktop,
234 LPCWSTR lpItemName,
235 LPCWSTR lpArguments,
236 LPCWSTR lpIconLocation,
237 INT iIcon,
238 LPCWSTR lpWorkingDirectory, /* Optional */
239 WORD wHotKey,
240 INT iShowCmd)
241 {
242 DYN_FUNCS Ole32;
243 WCHAR szLinkPath[MAX_PATH];
244 WCHAR szArguments[MAX_PATH];
245 WCHAR szCommand[MAX_PATH];
246 WIN32_FIND_DATAW FindData;
247 HANDLE hFind;
248 LPWSTR Ptr;
249 DWORD dwLength;
250 IShellLinkW* psl;
251 IPersistFile* ppf;
252 HRESULT hr;
253 BOOL bResult;
254
255 DPRINT ("AddDesktopItemW() called\n");
256
257 bResult = FALSE;
258
259 if (!GetDesktopPath (bCommonDesktop, szLinkPath))
260 {
261 DPRINT1 ("GetDesktopPath() failed\n");
262 return FALSE;
263 }
264 DPRINT ("Desktop path: '%S'\n", szLinkPath);
265
266 /* Make sure the path exists */
267 hFind = FindFirstFileW (szLinkPath,
268 &FindData);
269 if (hFind == INVALID_HANDLE_VALUE)
270 {
271 DPRINT ("'%S' does not exist\n", szLinkPath);
272
273 /* Create directory path */
274 if (!CreateDirectoryPath (szLinkPath, NULL))
275 return FALSE;
276 }
277 else
278 {
279 DPRINT ("'%S' exists\n", szLinkPath);
280 FindClose (hFind);
281 }
282
283 /* Append backslash, item name and ".lnk" extension */
284 wcscat (szLinkPath, L"\\");
285 wcscat (szLinkPath, lpItemName);
286 wcscat (szLinkPath, L".lnk");
287 DPRINT ("Link path: '%S'\n", szLinkPath);
288
289 /* Split 'lpArguments' string into command and arguments */
290 Ptr = wcschr (lpArguments, L' ');
291 DPRINT ("Ptr %p lpArguments %p\n", Ptr, lpArguments);
292 if (Ptr != NULL)
293 {
294 dwLength = (DWORD)(Ptr - lpArguments);
295 DPRINT ("dwLength %lu\n", dwLength);
296 memcpy (szCommand, lpArguments, dwLength * sizeof(WCHAR));
297 szCommand[dwLength] = 0;
298 Ptr++;
299 wcscpy (szArguments, Ptr);
300 }
301 else
302 {
303 wcscpy (szCommand, lpArguments);
304 szArguments[0] = 0;
305 }
306 DPRINT ("szCommand: '%S'\n", szCommand);
307 DPRINT ("szArguments: '%S'\n", szArguments);
308
309 /* Dynamically load ole32.dll */
310 if (!LoadDynamicImports(&DynOle32, &Ole32))
311 {
312 DPRINT1("USERENV: Unable to load OLE32.DLL\n");
313 return FALSE;
314 }
315
316 Ole32.fn.CoInitialize(NULL);
317
318 hr = Ole32.fn.CoCreateInstance(&CLSID_ShellLink,
319 NULL,
320 CLSCTX_INPROC_SERVER,
321 &IID_IShellLinkW,
322 (LPVOID*)&psl);
323 if (!SUCCEEDED(hr))
324 {
325 Ole32.fn.CoUninitialize();
326 UnloadDynamicImports(&Ole32);
327 return FALSE;
328 }
329
330 hr = psl->lpVtbl->QueryInterface(psl,
331 &IID_IPersistFile,
332 (LPVOID*)&ppf);
333 if (SUCCEEDED(hr))
334 {
335 psl->lpVtbl->SetDescription(psl,
336 lpItemName);
337
338 psl->lpVtbl->SetPath(psl,
339 szCommand);
340
341 psl->lpVtbl->SetArguments(psl,
342 szArguments);
343
344 psl->lpVtbl->SetIconLocation(psl,
345 lpIconLocation,
346 iIcon);
347
348 if (lpWorkingDirectory != NULL)
349 {
350 psl->lpVtbl->SetWorkingDirectory(psl,
351 lpWorkingDirectory);
352 }
353 else
354 {
355 psl->lpVtbl->SetWorkingDirectory(psl,
356 L"%HOMEDRIVE%%HOMEPATH%");
357 }
358
359 psl->lpVtbl->SetHotkey(psl,
360 wHotKey);
361
362 psl->lpVtbl->SetShowCmd(psl,
363 iShowCmd);
364
365 hr = ppf->lpVtbl->Save(ppf,
366 szLinkPath,
367 TRUE);
368 if (SUCCEEDED(hr))
369 bResult = TRUE;
370
371 ppf->lpVtbl->Release(ppf);
372 }
373
374 psl->lpVtbl->Release(psl);
375
376 Ole32.fn.CoUninitialize();
377
378 UnloadDynamicImports(&Ole32);
379
380 DPRINT ("AddDesktopItemW() done\n");
381
382 return bResult;
383 }
384
385
386 BOOL WINAPI
387 DeleteDesktopItemA (BOOL bCommonItem,
388 LPCSTR lpItemName)
389 {
390 UNICODE_STRING ItemName;
391 BOOL bResult;
392 NTSTATUS Status;
393
394 Status = RtlCreateUnicodeStringFromAsciiz(&ItemName,
395 (LPSTR)lpItemName);
396 if (!NT_SUCCESS(Status))
397 {
398 SetLastError (RtlNtStatusToDosError (Status));
399 return FALSE;
400 }
401
402 bResult = DeleteDesktopItemW(bCommonItem,
403 ItemName.Buffer);
404
405 RtlFreeUnicodeString(&ItemName);
406
407 return bResult;
408 }
409
410
411 BOOL WINAPI
412 DeleteDesktopItemW (BOOL bCommonItem,
413 LPCWSTR lpItemName)
414 {
415 WCHAR szLinkPath[MAX_PATH];
416
417 DPRINT ("DeleteDesktopItemW() called\n");
418
419 if (!GetDesktopPath (bCommonItem, szLinkPath))
420 {
421 DPRINT1 ("GetDesktopPath() failed\n");
422 return FALSE;
423 }
424
425 wcscat (szLinkPath, L"\\");
426 wcscat (szLinkPath, lpItemName);
427 wcscat (szLinkPath, L".lnk");
428 DPRINT ("Link path: '%S'\n", szLinkPath);
429
430 return DeleteFileW (szLinkPath);
431 }
432
433
434 BOOL WINAPI
435 CreateGroupA (LPCSTR lpGroupName,
436 BOOL bCommonGroup)
437 {
438 UNICODE_STRING GroupName;
439 BOOL bResult;
440 NTSTATUS Status;
441
442 Status = RtlCreateUnicodeStringFromAsciiz(&GroupName,
443 (LPSTR)lpGroupName);
444 if (!NT_SUCCESS(Status))
445 {
446 SetLastError (RtlNtStatusToDosError (Status));
447 return FALSE;
448 }
449
450 bResult = CreateGroupW(GroupName.Buffer, bCommonGroup);
451
452 RtlFreeUnicodeString(&GroupName);
453
454 return bResult;
455 }
456
457
458 BOOL WINAPI
459 CreateGroupW (LPCWSTR lpGroupName,
460 BOOL bCommonGroup)
461 {
462 WCHAR szGroupPath[MAX_PATH];
463
464 DPRINT1 ("CreateGroupW() called\n");
465
466 if (lpGroupName == NULL || *lpGroupName == 0)
467 return TRUE;
468
469 if (!GetProgramsPath (bCommonGroup, szGroupPath))
470 {
471 DPRINT1 ("GetProgramsPath() failed\n");
472 return FALSE;
473 }
474 DPRINT1 ("Programs path: '%S'\n", szGroupPath);
475
476 wcscat (szGroupPath, L"\\");
477 wcscat (szGroupPath, lpGroupName);
478 DPRINT1 ("Group path: '%S'\n", szGroupPath);
479
480 /* Create directory path */
481 if (!CreateDirectoryPath (szGroupPath, NULL))
482 return FALSE;
483
484 /* FIXME: Notify the shell */
485
486 DPRINT1 ("CreateGroupW() done\n");
487
488 return TRUE;
489 }
490
491
492 BOOL WINAPI
493 DeleteGroupA (LPCSTR lpGroupName,
494 BOOL bCommonGroup)
495 {
496 UNICODE_STRING GroupName;
497 BOOL bResult;
498 NTSTATUS Status;
499
500 Status = RtlCreateUnicodeStringFromAsciiz(&GroupName,
501 (LPSTR)lpGroupName);
502 if (!NT_SUCCESS(Status))
503 {
504 SetLastError (RtlNtStatusToDosError (Status));
505 return FALSE;
506 }
507
508 bResult = DeleteGroupW(GroupName.Buffer, bCommonGroup);
509
510 RtlFreeUnicodeString(&GroupName);
511
512 return bResult;
513 }
514
515
516 BOOL WINAPI
517 DeleteGroupW (LPCWSTR lpGroupName,
518 BOOL bCommonGroup)
519 {
520 WCHAR szGroupPath[MAX_PATH];
521
522 DPRINT ("DeleteGroupW() called\n");
523
524 if (lpGroupName == NULL || *lpGroupName == 0)
525 return TRUE;
526
527 if (!GetProgramsPath (bCommonGroup, szGroupPath))
528 {
529 DPRINT1 ("GetProgramsPath() failed\n");
530 return FALSE;
531 }
532 DPRINT ("Programs path: '%S'\n", szGroupPath);
533
534 wcscat (szGroupPath, L"\\");
535 wcscat (szGroupPath, lpGroupName);
536 DPRINT ("Group path: '%S'\n", szGroupPath);
537
538 /* Remove directory path */
539 if (!RemoveDirectoryPath (szGroupPath))
540 return FALSE;
541
542 /* FIXME: Notify the shell */
543
544 DPRINT ("DeleteGroupW() done\n");
545
546 return TRUE;
547 }
548
549
550 BOOL WINAPI
551 AddItemA (LPCSTR lpGroupName, /* Optional */
552 BOOL bCommonGroup,
553 LPCSTR lpItemName,
554 LPCSTR lpArguments,
555 LPCSTR lpIconLocation,
556 INT iIcon,
557 LPCSTR lpWorkingDirectory, /* Optional */
558 WORD wHotKey,
559 INT iShowCmd)
560 {
561 UNICODE_STRING GroupName;
562 UNICODE_STRING ItemName;
563 UNICODE_STRING Arguments;
564 UNICODE_STRING IconLocation;
565 UNICODE_STRING WorkingDirectory;
566 BOOL bResult;
567 NTSTATUS Status;
568
569 Status = RtlCreateUnicodeStringFromAsciiz(&ItemName,
570 (LPSTR)lpItemName);
571 if (!NT_SUCCESS(Status))
572 {
573 SetLastError (RtlNtStatusToDosError (Status));
574 return FALSE;
575 }
576
577 Status = RtlCreateUnicodeStringFromAsciiz(&Arguments,
578 (LPSTR)lpArguments);
579 if (!NT_SUCCESS(Status))
580 {
581 RtlFreeUnicodeString(&ItemName);
582 SetLastError (RtlNtStatusToDosError (Status));
583 return FALSE;
584 }
585
586 Status = RtlCreateUnicodeStringFromAsciiz(&IconLocation,
587 (LPSTR)lpIconLocation);
588 if (!NT_SUCCESS(Status))
589 {
590 RtlFreeUnicodeString(&Arguments);
591 RtlFreeUnicodeString(&ItemName);
592 SetLastError (RtlNtStatusToDosError (Status));
593 return FALSE;
594 }
595
596 if (lpGroupName != NULL)
597 {
598 Status = RtlCreateUnicodeStringFromAsciiz(&GroupName,
599 (LPSTR)lpGroupName);
600 if (!NT_SUCCESS(Status))
601 {
602 RtlFreeUnicodeString(&IconLocation);
603 RtlFreeUnicodeString(&Arguments);
604 RtlFreeUnicodeString(&ItemName);
605 SetLastError (RtlNtStatusToDosError (Status));
606 return FALSE;
607 }
608 }
609
610 if (lpWorkingDirectory != NULL)
611 {
612 Status = RtlCreateUnicodeStringFromAsciiz(&WorkingDirectory,
613 (LPSTR)lpWorkingDirectory);
614 if (!NT_SUCCESS(Status))
615 {
616 if (lpGroupName != NULL)
617 {
618 RtlFreeUnicodeString(&GroupName);
619 }
620 RtlFreeUnicodeString(&IconLocation);
621 RtlFreeUnicodeString(&Arguments);
622 RtlFreeUnicodeString(&ItemName);
623 SetLastError (RtlNtStatusToDosError (Status));
624 return FALSE;
625 }
626 }
627
628 bResult = AddItemW((lpGroupName != NULL) ? GroupName.Buffer : NULL,
629 bCommonGroup,
630 ItemName.Buffer,
631 Arguments.Buffer,
632 IconLocation.Buffer,
633 iIcon,
634 (lpWorkingDirectory != NULL) ? WorkingDirectory.Buffer : NULL,
635 wHotKey,
636 iShowCmd);
637
638 if (lpGroupName != NULL)
639 {
640 RtlFreeUnicodeString(&GroupName);
641 }
642
643 if (lpWorkingDirectory != NULL)
644 {
645 RtlFreeUnicodeString(&WorkingDirectory);
646 }
647
648 RtlFreeUnicodeString(&IconLocation);
649 RtlFreeUnicodeString(&Arguments);
650 RtlFreeUnicodeString(&ItemName);
651
652 return bResult;
653 }
654
655
656 BOOL WINAPI
657 AddItemW (LPCWSTR lpGroupName, /* Optional */
658 BOOL bCommonGroup,
659 LPCWSTR lpItemName,
660 LPCWSTR lpArguments,
661 LPCWSTR lpIconLocation,
662 INT iIcon,
663 LPCWSTR lpWorkingDirectory, /* Optional */
664 WORD wHotKey,
665 INT iShowCmd)
666 {
667 DYN_FUNCS Ole32;
668 WCHAR szLinkPath[MAX_PATH];
669 WCHAR szArguments[MAX_PATH];
670 WCHAR szCommand[MAX_PATH];
671 WIN32_FIND_DATAW FindData;
672 HANDLE hFind;
673 LPWSTR Ptr;
674 DWORD dwLength;
675 IShellLinkW* psl;
676 IPersistFile* ppf;
677 HRESULT hr;
678 BOOL bResult;
679
680 DPRINT ("AddItemW() called\n");
681
682 bResult = FALSE;
683
684 if (!GetProgramsPath (bCommonGroup, szLinkPath))
685 {
686 DPRINT1 ("GetProgramsPath() failed\n");
687 return FALSE;
688 }
689
690 DPRINT ("Programs path: '%S'\n", szLinkPath);
691
692 if (lpGroupName != NULL && *lpGroupName != 0)
693 {
694 wcscat (szLinkPath, L"\\");
695 wcscat (szLinkPath, lpGroupName);
696
697 /* Make sure the path exists */
698 hFind = FindFirstFileW (szLinkPath,
699 &FindData);
700 if (hFind == INVALID_HANDLE_VALUE)
701 {
702 DPRINT ("'%S' does not exist\n", szLinkPath);
703 if (!CreateGroupW (lpGroupName,
704 bCommonGroup))
705 return FALSE;
706 }
707 else
708 {
709 DPRINT ("'%S' exists\n", szLinkPath);
710 FindClose (hFind);
711 }
712 }
713
714 wcscat (szLinkPath, L"\\");
715 wcscat (szLinkPath, lpItemName);
716 wcscat (szLinkPath, L".lnk");
717 DPRINT ("Link path: '%S'\n", szLinkPath);
718
719 /* Split 'lpArguments' string into command and arguments */
720 Ptr = wcschr (lpArguments, L' ');
721 DPRINT ("Ptr %p lpArguments %p\n", Ptr, lpArguments);
722 if (Ptr != NULL)
723 {
724 dwLength = (DWORD)(Ptr - lpArguments);
725 DPRINT ("dwLength %lu\n", dwLength);
726 memcpy (szCommand, lpArguments, dwLength * sizeof(WCHAR));
727 szCommand[dwLength] = 0;
728 Ptr++;
729 wcscpy (szArguments, Ptr);
730 }
731 else
732 {
733 wcscpy (szCommand, lpArguments);
734 szArguments[0] = 0;
735 }
736 DPRINT ("szCommand: '%S'\n", szCommand);
737 DPRINT ("szArguments: '%S'\n", szArguments);
738
739 /* Dynamically load ole32.dll */
740 if (!LoadDynamicImports(&DynOle32, &Ole32))
741 {
742 DPRINT1("USERENV: Unable to load OLE32.DLL\n");
743 return FALSE;
744 }
745
746 Ole32.fn.CoInitialize(NULL);
747
748 hr = Ole32.fn.CoCreateInstance(&CLSID_ShellLink,
749 NULL,
750 CLSCTX_INPROC_SERVER,
751 &IID_IShellLinkW,
752 (LPVOID*)&psl);
753 if (!SUCCEEDED(hr))
754 {
755 Ole32.fn.CoUninitialize();
756 UnloadDynamicImports(&Ole32);
757 return FALSE;
758 }
759
760 hr = psl->lpVtbl->QueryInterface(psl,
761 &IID_IPersistFile,
762 (LPVOID*)&ppf);
763 if (SUCCEEDED(hr))
764 {
765 psl->lpVtbl->SetDescription(psl,
766 lpItemName);
767
768 psl->lpVtbl->SetPath(psl,
769 szCommand);
770
771 psl->lpVtbl->SetArguments(psl,
772 szArguments);
773
774 psl->lpVtbl->SetIconLocation(psl,
775 lpIconLocation,
776 iIcon);
777
778 if (lpWorkingDirectory != NULL)
779 {
780 psl->lpVtbl->SetWorkingDirectory(psl,
781 lpWorkingDirectory);
782 }
783 else
784 {
785 psl->lpVtbl->SetWorkingDirectory(psl,
786 L"%HOMEDRIVE%%HOMEPATH%");
787 }
788
789 psl->lpVtbl->SetHotkey(psl,
790 wHotKey);
791
792 psl->lpVtbl->SetShowCmd(psl,
793 iShowCmd);
794
795 hr = ppf->lpVtbl->Save(ppf,
796 szLinkPath,
797 TRUE);
798 if (SUCCEEDED(hr))
799 bResult = TRUE;
800
801 ppf->lpVtbl->Release(ppf);
802 }
803
804 psl->lpVtbl->Release(psl);
805
806 Ole32.fn.CoUninitialize();
807 UnloadDynamicImports(&Ole32);
808
809 DPRINT ("AddItemW() done\n");
810
811 return bResult;
812 }
813
814
815 BOOL WINAPI
816 DeleteItemA (LPCSTR lpGroupName, /* Optional */
817 BOOL bCommonGroup,
818 LPCSTR lpItemName,
819 BOOL bDeleteGroup)
820 {
821 UNICODE_STRING GroupName;
822 UNICODE_STRING ItemName;
823 BOOL bResult;
824 NTSTATUS Status;
825
826 if (lpGroupName != NULL)
827 {
828 Status = RtlCreateUnicodeStringFromAsciiz(&GroupName,
829 (LPSTR)lpGroupName);
830 if (!NT_SUCCESS(Status))
831 {
832 SetLastError (RtlNtStatusToDosError (Status));
833 return FALSE;
834 }
835 }
836
837 Status = RtlCreateUnicodeStringFromAsciiz(&ItemName,
838 (LPSTR)lpItemName);
839 if (!NT_SUCCESS(Status))
840 {
841 if (lpGroupName != NULL)
842 {
843 RtlFreeUnicodeString(&GroupName);
844 }
845
846 SetLastError (RtlNtStatusToDosError (Status));
847 return FALSE;
848 }
849
850 bResult = DeleteItemW((lpGroupName != NULL) ? GroupName.Buffer : NULL,
851 bCommonGroup,
852 ItemName.Buffer,
853 bDeleteGroup);
854
855 RtlFreeUnicodeString(&ItemName);
856 if (lpGroupName != NULL)
857 {
858 RtlFreeUnicodeString(&GroupName);
859 }
860
861 return bResult;
862 }
863
864
865 BOOL WINAPI
866 DeleteItemW (LPCWSTR lpGroupName, /* Optional */
867 BOOL bCommonGroup,
868 LPCWSTR lpItemName,
869 BOOL bDeleteGroup)
870 {
871 WCHAR szItemPath[MAX_PATH];
872 LPWSTR Ptr;
873
874 DPRINT ("DeleteItemW() called\n");
875
876 if (!GetProgramsPath (bCommonGroup, szItemPath))
877 {
878 DPRINT1 ("GetProgramsPath() failed\n");
879 return FALSE;
880 }
881 DPRINT ("Programs path: '%S'\n", szItemPath);
882
883 if (lpGroupName != NULL && *lpGroupName != 0)
884 {
885 wcscat (szItemPath, L"\\");
886 wcscat (szItemPath, lpGroupName);
887 }
888
889 wcscat (szItemPath, L"\\");
890 wcscat (szItemPath, lpItemName);
891 wcscat (szItemPath, L".lnk");
892 DPRINT ("Item path: '%S'\n", szItemPath);
893
894 if (!DeleteFileW (szItemPath))
895 return FALSE;
896
897 /* FIXME: Notify the shell */
898
899 if (bDeleteGroup)
900 {
901 Ptr = wcsrchr (szItemPath, L'\\');
902 if (Ptr == NULL)
903 return TRUE;
904
905 *Ptr = 0;
906 DPRINT ("Item path: '%S'\n", szItemPath);
907 if (RemoveDirectoryW (szItemPath))
908 {
909 /* FIXME: Notify the shell */
910 }
911 }
912
913 DPRINT ("DeleteItemW() done\n");
914
915 return TRUE;
916 }
917
918 /* EOF */