ReactOS  0.4.12-dev-685-gf36cbf7
desktop.c
Go to the documentation of this file.
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: dll/win32/userenv/desktop.c
23  * PURPOSE: Desktop and start menu support functions.
24  * PROGRAMMER: Eric Kohl
25  */
26 
27 #include "precomp.h"
28 
29 #include <shlobj.h>
30 
31 #define NDEBUG
32 #include <debug.h>
33 
34 /* FUNCTIONS ***************************************************************/
35 
36 static
37 BOOL
38 GetDesktopPath(BOOL bCommonPath,
39  LPWSTR lpDesktopPath)
40 {
43  DWORD dwType;
44  HKEY hKey;
45  LONG Error;
46 
47  DPRINT("GetDesktopPath() called\n");
48 
50  L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
51  0,
53  &hKey);
54  if (Error != ERROR_SUCCESS)
55  {
56  DPRINT1("RegOpenKeyExW() failed\n");
58  return FALSE;
59  }
60 
61  dwLength = MAX_PATH * sizeof(WCHAR);
62  Error = RegQueryValueExW(hKey,
63  bCommonPath ? L"Common Desktop" : L"Desktop",
64  0,
65  &dwType,
66  (LPBYTE)szPath,
67  &dwLength);
68  if (Error != ERROR_SUCCESS)
69  {
70  DPRINT1("RegQueryValueExW() failed\n");
71  RegCloseKey(hKey);
73  return FALSE;
74  }
75 
76  RegCloseKey(hKey);
77 
78  if (dwType == REG_EXPAND_SZ)
79  {
81  lpDesktopPath,
82  MAX_PATH);
83  }
84  else
85  {
86  wcscpy(lpDesktopPath, szPath);
87  }
88 
89  DPRINT("GetDesktopPath() done\n");
90 
91  return TRUE;
92 }
93 
94 
95 static
96 BOOL
97 GetProgramsPath(BOOL bCommonPath,
98  LPWSTR lpProgramsPath)
99 {
101  DWORD dwLength;
102  DWORD dwType;
103  HKEY hKey;
104  LONG Error;
105 
106  DPRINT("GetProgramsPath() called\n");
107 
109  L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
110  0,
112  &hKey);
113  if (Error != ERROR_SUCCESS)
114  {
115  DPRINT1("RegOpenKeyExW() failed\n");
117  return FALSE;
118  }
119 
120  dwLength = MAX_PATH * sizeof(WCHAR);
121  Error = RegQueryValueExW(hKey,
122  bCommonPath ? L"Common Programs" : L"Programs",
123  0,
124  &dwType,
125  (LPBYTE)szPath,
126  &dwLength);
127  if (Error != ERROR_SUCCESS)
128  {
129  DPRINT1("RegQueryValueExW() failed\n");
130  RegCloseKey(hKey);
132  return FALSE;
133  }
134 
135  RegCloseKey(hKey);
136 
137  if (dwType == REG_EXPAND_SZ)
138  {
140  lpProgramsPath,
141  MAX_PATH);
142  }
143  else
144  {
145  wcscpy(lpProgramsPath,
146  szPath);
147  }
148 
149  DPRINT("GetProgramsPath() done\n");
150 
151  return TRUE;
152 }
153 
154 
155 BOOL
156 WINAPI
157 AddDesktopItemA(BOOL bCommonItem,
158  LPCSTR lpItemName,
159  LPCSTR lpArguments,
160  LPCSTR lpIconLocation,
161  INT iIcon,
162  LPCSTR lpWorkingDirectory, /* Optional */
163  WORD wHotKey,
164  INT iShowCmd)
165 {
166  UNICODE_STRING ItemName;
167  UNICODE_STRING Arguments;
169  UNICODE_STRING WorkingDirectory;
170  BOOL bResult;
171 
172  if (!RtlCreateUnicodeStringFromAsciiz(&ItemName,
173  (LPSTR)lpItemName))
174  {
176  return FALSE;
177  }
178 
179  if (!RtlCreateUnicodeStringFromAsciiz(&Arguments,
180  (LPSTR)lpArguments))
181  {
182  RtlFreeUnicodeString(&ItemName);
184  return FALSE;
185  }
186 
188  (LPSTR)lpIconLocation))
189  {
190  RtlFreeUnicodeString(&Arguments);
191  RtlFreeUnicodeString(&ItemName);
193  return FALSE;
194  }
195 
196  if (lpWorkingDirectory != NULL)
197  {
198  if (!RtlCreateUnicodeStringFromAsciiz(&WorkingDirectory,
199  (LPSTR)lpWorkingDirectory))
200  {
202  RtlFreeUnicodeString(&Arguments);
203  RtlFreeUnicodeString(&ItemName);
205  return FALSE;
206  }
207  }
208 
209  bResult = AddDesktopItemW(bCommonItem,
210  ItemName.Buffer,
211  Arguments.Buffer,
212  IconLocation.Buffer,
213  iIcon,
214  (lpWorkingDirectory != NULL) ? WorkingDirectory.Buffer : NULL,
215  wHotKey,
216  iShowCmd);
217 
218  if (lpWorkingDirectory != NULL)
219  {
220  RtlFreeUnicodeString(&WorkingDirectory);
221  }
222 
224  RtlFreeUnicodeString(&Arguments);
225  RtlFreeUnicodeString(&ItemName);
226 
227  return bResult;
228 }
229 
230 
231 BOOL
232 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,
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
387 WINAPI
389  LPCSTR lpItemName)
390 {
391  UNICODE_STRING ItemName;
392  BOOL bResult;
393 
394  if (!RtlCreateUnicodeStringFromAsciiz(&ItemName,
395  (LPSTR)lpItemName))
396  {
398  return FALSE;
399  }
400 
401  bResult = DeleteDesktopItemW(bCommonItem,
402  ItemName.Buffer);
403 
404  RtlFreeUnicodeString(&ItemName);
405 
406  return bResult;
407 }
408 
409 
410 BOOL
411 WINAPI
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
435 WINAPI
436 CreateGroupA(LPCSTR lpGroupName,
437  BOOL bCommonGroup)
438 {
439  UNICODE_STRING GroupName;
440  BOOL bResult;
441 
442  if (!RtlCreateUnicodeStringFromAsciiz(&GroupName,
443  (LPSTR)lpGroupName))
444  {
446  return FALSE;
447  }
448 
449  bResult = CreateGroupW(GroupName.Buffer, bCommonGroup);
450 
451  RtlFreeUnicodeString(&GroupName);
452 
453  return bResult;
454 }
455 
456 
457 BOOL
458 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
493 WINAPI
494 DeleteGroupA(LPCSTR lpGroupName,
495  BOOL bCommonGroup)
496 {
497  UNICODE_STRING GroupName;
498  BOOL bResult;
499 
500  if (!RtlCreateUnicodeStringFromAsciiz(&GroupName,
501  (LPSTR)lpGroupName))
502  {
504  return FALSE;
505  }
506 
507  bResult = DeleteGroupW(GroupName.Buffer, bCommonGroup);
508 
509  RtlFreeUnicodeString(&GroupName);
510 
511  return bResult;
512 }
513 
514 
515 BOOL
516 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
551 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;
566  UNICODE_STRING WorkingDirectory;
567  BOOL bResult;
568 
569  if (!RtlCreateUnicodeStringFromAsciiz(&ItemName,
570  (LPSTR)lpItemName))
571  {
573  return FALSE;
574  }
575 
576  if (!RtlCreateUnicodeStringFromAsciiz(&Arguments,
577  (LPSTR)lpArguments))
578  {
579  RtlFreeUnicodeString(&ItemName);
581  return FALSE;
582  }
583 
585  (LPSTR)lpIconLocation))
586  {
587  RtlFreeUnicodeString(&Arguments);
588  RtlFreeUnicodeString(&ItemName);
590  return FALSE;
591  }
592 
593  if (lpGroupName != NULL)
594  {
595  if (!RtlCreateUnicodeStringFromAsciiz(&GroupName,
596  (LPSTR)lpGroupName))
597  {
599  RtlFreeUnicodeString(&Arguments);
600  RtlFreeUnicodeString(&ItemName);
602  return FALSE;
603  }
604  }
605 
606  if (lpWorkingDirectory != NULL)
607  {
608  if (!RtlCreateUnicodeStringFromAsciiz(&WorkingDirectory,
609  (LPSTR)lpWorkingDirectory))
610  {
611  if (lpGroupName != NULL)
612  {
613  RtlFreeUnicodeString(&GroupName);
614  }
616  RtlFreeUnicodeString(&Arguments);
617  RtlFreeUnicodeString(&ItemName);
619  return FALSE;
620  }
621  }
622 
623  bResult = AddItemW((lpGroupName != NULL) ? GroupName.Buffer : NULL,
624  bCommonGroup,
625  ItemName.Buffer,
626  Arguments.Buffer,
627  IconLocation.Buffer,
628  iIcon,
629  (lpWorkingDirectory != NULL) ? WorkingDirectory.Buffer : NULL,
630  wHotKey,
631  iShowCmd);
632 
633  if (lpGroupName != NULL)
634  {
635  RtlFreeUnicodeString(&GroupName);
636  }
637 
638  if (lpWorkingDirectory != NULL)
639  {
640  RtlFreeUnicodeString(&WorkingDirectory);
641  }
642 
644  RtlFreeUnicodeString(&Arguments);
645  RtlFreeUnicodeString(&ItemName);
646 
647  return bResult;
648 }
649 
650 
651 BOOL
652 WINAPI
653 AddItemW(LPCWSTR lpGroupName, /* Optional */
654  BOOL bCommonGroup,
655  LPCWSTR lpItemName,
656  LPCWSTR lpArguments,
657  LPCWSTR lpIconLocation,
658  INT iIcon,
659  LPCWSTR lpWorkingDirectory, /* Optional */
660  WORD wHotKey,
661  INT iShowCmd)
662 {
663  DYN_FUNCS Ole32;
664  WCHAR szLinkPath[MAX_PATH];
665  WCHAR szArguments[MAX_PATH];
666  WCHAR szCommand[MAX_PATH];
667  WIN32_FIND_DATAW FindData;
668  HANDLE hFind;
669  LPWSTR Ptr;
670  DWORD dwLength;
671  IShellLinkW* psl;
672  IPersistFile* ppf;
673  HRESULT hr;
674  BOOL bResult;
675 
676  DPRINT("AddItemW() called\n");
677 
678  bResult = FALSE;
679 
680  if (!GetProgramsPath(bCommonGroup, szLinkPath))
681  {
682  DPRINT1("GetProgramsPath() failed\n");
683  return FALSE;
684  }
685 
686  DPRINT("Programs path: '%S'\n", szLinkPath);
687 
688  if (lpGroupName != NULL && *lpGroupName != 0)
689  {
690  wcscat(szLinkPath, L"\\");
691  wcscat(szLinkPath, lpGroupName);
692 
693  /* Make sure the path exists */
694  hFind = FindFirstFileW(szLinkPath,
695  &FindData);
696  if (hFind == INVALID_HANDLE_VALUE)
697  {
698  DPRINT("'%S' does not exist\n", szLinkPath);
699  if (!CreateGroupW(lpGroupName,
700  bCommonGroup))
701  return FALSE;
702  }
703  else
704  {
705  DPRINT("'%S' exists\n", szLinkPath);
706  FindClose(hFind);
707  }
708  }
709 
710  wcscat(szLinkPath, L"\\");
711  wcscat(szLinkPath, lpItemName);
712  wcscat(szLinkPath, L".lnk");
713  DPRINT("Link path: '%S'\n", szLinkPath);
714 
715  /* Split 'lpArguments' string into command and arguments */
716  Ptr = wcschr(lpArguments, L' ');
717  DPRINT("Ptr %p lpArguments %p\n", Ptr, lpArguments);
718  if (Ptr != NULL)
719  {
720  dwLength = (DWORD)(Ptr - lpArguments);
721  DPRINT("dwLength %lu\n", dwLength);
722  memcpy(szCommand, lpArguments, dwLength * sizeof(WCHAR));
723  szCommand[dwLength] = 0;
724  Ptr++;
725  wcscpy(szArguments, Ptr);
726  }
727  else
728  {
729  wcscpy(szCommand, lpArguments);
730  szArguments[0] = 0;
731  }
732  DPRINT("szCommand: '%S'\n", szCommand);
733  DPRINT("szArguments: '%S'\n", szArguments);
734 
735  /* Dynamically load ole32.dll */
736  if (!LoadDynamicImports(&DynOle32, &Ole32))
737  {
738  DPRINT1("USERENV: Unable to load OLE32.DLL\n");
739  return FALSE;
740  }
741 
742  Ole32.fn.CoInitialize(NULL);
743 
744  hr = Ole32.fn.CoCreateInstance(&CLSID_ShellLink,
745  NULL,
746  CLSCTX_INPROC_SERVER,
747  &IID_IShellLinkW,
748  (LPVOID*)&psl);
749  if (!SUCCEEDED(hr))
750  {
751  Ole32.fn.CoUninitialize();
752  UnloadDynamicImports(&Ole32);
753  return FALSE;
754  }
755 
756  hr = psl->lpVtbl->QueryInterface(psl,
758  (LPVOID*)&ppf);
759  if (SUCCEEDED(hr))
760  {
761  psl->lpVtbl->SetDescription(psl,
762  lpItemName);
763 
764  psl->lpVtbl->SetPath(psl,
765  szCommand);
766 
767  psl->lpVtbl->SetArguments(psl,
768  szArguments);
769 
770  psl->lpVtbl->SetIconLocation(psl,
771  lpIconLocation,
772  iIcon);
773 
774  if (lpWorkingDirectory != NULL)
775  {
776  psl->lpVtbl->SetWorkingDirectory(psl,
777  lpWorkingDirectory);
778  }
779  else
780  {
781  psl->lpVtbl->SetWorkingDirectory(psl,
782  L"%HOMEDRIVE%%HOMEPATH%");
783  }
784 
785  psl->lpVtbl->SetHotkey(psl,
786  wHotKey);
787 
788  psl->lpVtbl->SetShowCmd(psl,
789  iShowCmd);
790 
791  hr = ppf->lpVtbl->Save(ppf,
792  szLinkPath,
793  TRUE);
794  if (SUCCEEDED(hr))
795  bResult = TRUE;
796 
797  ppf->lpVtbl->Release(ppf);
798  }
799 
800  psl->lpVtbl->Release(psl);
801 
802  Ole32.fn.CoUninitialize();
803  UnloadDynamicImports(&Ole32);
804 
805  DPRINT("AddItemW() done\n");
806 
807  return bResult;
808 }
809 
810 
811 BOOL
812 WINAPI
813 DeleteItemA(LPCSTR lpGroupName, /* Optional */
814  BOOL bCommonGroup,
815  LPCSTR lpItemName,
816  BOOL bDeleteGroup)
817 {
818  UNICODE_STRING GroupName;
819  UNICODE_STRING ItemName;
820  BOOL bResult;
821 
822  if (lpGroupName != NULL)
823  {
824  if (!RtlCreateUnicodeStringFromAsciiz(&GroupName,
825  (LPSTR)lpGroupName))
826  {
828  return FALSE;
829  }
830  }
831 
832  if (!RtlCreateUnicodeStringFromAsciiz(&ItemName,
833  (LPSTR)lpItemName))
834  {
835  if (lpGroupName != NULL)
836  {
837  RtlFreeUnicodeString(&GroupName);
838  }
839 
841  return FALSE;
842  }
843 
844  bResult = DeleteItemW((lpGroupName != NULL) ? GroupName.Buffer : NULL,
845  bCommonGroup,
846  ItemName.Buffer,
847  bDeleteGroup);
848 
849  RtlFreeUnicodeString(&ItemName);
850  if (lpGroupName != NULL)
851  {
852  RtlFreeUnicodeString(&GroupName);
853  }
854 
855  return bResult;
856 }
857 
858 
859 BOOL
860 WINAPI
861 DeleteItemW(LPCWSTR lpGroupName, /* Optional */
862  BOOL bCommonGroup,
863  LPCWSTR lpItemName,
864  BOOL bDeleteGroup)
865 {
866  WCHAR szItemPath[MAX_PATH];
867  LPWSTR Ptr;
868 
869  DPRINT("DeleteItemW() called\n");
870 
871  if (!GetProgramsPath(bCommonGroup, szItemPath))
872  {
873  DPRINT1("GetProgramsPath() failed\n");
874  return FALSE;
875  }
876  DPRINT("Programs path: '%S'\n", szItemPath);
877 
878  if (lpGroupName != NULL && *lpGroupName != 0)
879  {
880  wcscat(szItemPath, L"\\");
881  wcscat(szItemPath, lpGroupName);
882  }
883 
884  wcscat(szItemPath, L"\\");
885  wcscat(szItemPath, lpItemName);
886  wcscat(szItemPath, L".lnk");
887  DPRINT("Item path: '%S'\n", szItemPath);
888 
889  if (!DeleteFileW(szItemPath))
890  return FALSE;
891 
892  /* FIXME: Notify the shell */
893 
894  if (bDeleteGroup)
895  {
896  Ptr = wcsrchr(szItemPath, L'\\');
897  if (Ptr == NULL)
898  return TRUE;
899 
900  *Ptr = 0;
901  DPRINT("Item path: '%S'\n", szItemPath);
902  if (RemoveDirectoryW(szItemPath))
903  {
904  /* FIXME: Notify the shell */
905  }
906  }
907 
908  DPRINT("DeleteItemW() done\n");
909 
910  return TRUE;
911 }
912 
913 /* EOF */
static BOOL GetProgramsPath(BOOL bCommonPath, LPWSTR lpProgramsPath)
Definition: desktop.c:97
BOOL WINAPI DeleteItemA(LPCSTR lpGroupName, BOOL bCommonGroup, LPCSTR lpItemName, BOOL bDeleteGroup)
Definition: desktop.c:813
#define TRUE
Definition: types.h:120
BOOL WINAPI AddDesktopItemW(BOOL bCommonDesktop, LPCWSTR lpItemName, LPCWSTR lpArguments, LPCWSTR lpIconLocation, INT iIcon, LPCWSTR lpWorkingDirectory, WORD wHotKey, INT iShowCmd)
Definition: desktop.c:233
BOOL WINAPI DeleteDesktopItemW(BOOL bCommonItem, LPCWSTR lpItemName)
Definition: desktop.c:412
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT hr
Definition: shlfolder.c:183
BOOL WINAPI AddDesktopItemA(BOOL bCommonItem, LPCSTR lpItemName, LPCSTR lpArguments, LPCSTR lpIconLocation, INT iIcon, LPCSTR lpWorkingDirectory, WORD wHotKey, INT iShowCmd)
Definition: desktop.c:157
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define DWORD
Definition: msvc.h:34
#define HKEY_CURRENT_USER
Definition: winreg.h:11
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
union _DYN_FUNCS::@529 fn
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
char * LPSTR
Definition: xmlstorage.h:182
#define WCHAR
Definition: msvc.h:43
int32_t INT
Definition: typedefs.h:56
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
VOID UnloadDynamicImports(PDYN_FUNCS DynFuncs)
Definition: misc.c:259
long LONG
Definition: pedump.c:60
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI AddItemA(LPCSTR lpGroupName, BOOL bCommonGroup, LPCSTR lpItemName, LPCSTR lpArguments, LPCSTR lpIconLocation, INT iIcon, LPCSTR lpWorkingDirectory, WORD wHotKey, INT iShowCmd)
Definition: desktop.c:552
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
BOOL WINAPI AddItemW(LPCWSTR lpGroupName, BOOL bCommonGroup, LPCWSTR lpItemName, LPCWSTR lpArguments, LPCWSTR lpIconLocation, INT iIcon, LPCWSTR lpWorkingDirectory, WORD wHotKey, INT iShowCmd)
Definition: desktop.c:653
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
static BOOL GetDesktopPath(BOOL bCommonPath, LPWSTR lpDesktopPath)
Definition: desktop.c:38
const char * LPCSTR
Definition: xmlstorage.h:183
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
BOOL RemoveDirectoryPath(LPCWSTR lpPathName)
Definition: directory.c:324
unsigned int BOOL
Definition: ntddk_ex.h:94
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
static DWORD DWORD * dwLength
Definition: fusion.c:83
LONG HRESULT
Definition: typedefs.h:77
BOOL WINAPI DeleteGroupW(LPCWSTR lpGroupName, BOOL bCommonGroup)
Definition: desktop.c:517
#define MAX_PATH
Definition: compat.h:26
unsigned short WORD
Definition: ntddk_ex.h:93
nsrefcnt Release()
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
BOOL Error
Definition: chkdsk.c:66
#define SetLastError(x)
Definition: compat.h:409
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
BOOL LoadDynamicImports(PDYN_MODULE Module, PDYN_FUNCS DynFuncs)
Definition: misc.c:223
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define WINAPI
Definition: msvc.h:20
DYN_MODULE DynOle32
Definition: misc.c:204
BOOL CreateDirectoryPath(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: directory.c:176
LPCWSTR szPath
Definition: env.c:35
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI CreateGroupW(LPCWSTR lpGroupName, BOOL bCommonGroup)
Definition: desktop.c:459
#define DPRINT1
Definition: precomp.h:8
BOOL WINAPI CreateGroupA(LPCSTR lpGroupName, BOOL bCommonGroup)
Definition: desktop.c:436
const GUID IID_IPersistFile
BOOL WINAPI DeleteDesktopItemA(BOOL bCommonItem, LPCSTR lpItemName)
Definition: desktop.c:388
BOOL WINAPI DeleteGroupA(LPCSTR lpGroupName, BOOL bCommonGroup)
Definition: desktop.c:494
BOOL WINAPI DeleteItemW(LPCWSTR lpGroupName, BOOL bCommonGroup, LPCWSTR lpItemName, BOOL bDeleteGroup)
Definition: desktop.c:861
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
const PARAFORMAT * ppf
Definition: msvc.h:85
WCHAR * LPWSTR
Definition: xmlstorage.h:184
nsresult QueryInterface(nsIIDRef riid, void **result)
#define SUCCEEDED(hr)
Definition: intsafe.h:57
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502