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