1 /* $Id: desktop.c,v 1.9 2004/08/15 19:02:40 chorns Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/userenv/desktop.c
6 * PURPOSE: Desktop and start menu support functions.
7 * PROGRAMMER: Eric Kohl
14 /* FUNCTIONS ***************************************************************/
17 GetDesktopPath (BOOL bCommonPath
,
20 WCHAR szPath
[MAX_PATH
];
25 DPRINT ("GetDesktopPath() called\n");
27 if (RegOpenKeyExW (HKEY_CURRENT_USER
,
28 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
33 DPRINT1 ("RegOpenKeyExW() failed\n");
37 dwLength
= MAX_PATH
* sizeof(WCHAR
);
38 if (RegQueryValueExW (hKey
,
39 bCommonPath
? L
"Common Desktop" : L
"Desktop",
45 DPRINT1 ("RegQueryValueExW() failed\n");
52 if (dwType
== REG_EXPAND_SZ
)
54 ExpandEnvironmentStringsW (szPath
,
60 wcscpy (lpDesktopPath
, szPath
);
63 DPRINT ("GetDesktopPath() done\n");
70 GetProgramsPath (BOOL bCommonPath
,
71 LPWSTR lpProgramsPath
)
73 WCHAR szPath
[MAX_PATH
];
78 DPRINT ("GetProgramsPath() called\n");
80 if (RegOpenKeyExW (HKEY_CURRENT_USER
,
81 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
86 DPRINT1 ("RegOpenKeyExW() failed\n");
90 dwLength
= MAX_PATH
* sizeof(WCHAR
);
91 if (RegQueryValueExW (hKey
,
92 bCommonPath
? L
"Common Programs" : L
"Programs",
98 DPRINT1 ("RegQueryValueExW() failed\n");
105 if (dwType
== REG_EXPAND_SZ
)
107 ExpandEnvironmentStringsW (szPath
,
113 wcscpy (lpProgramsPath
,
117 DPRINT ("GetProgramsPath() done\n");
124 AddDesktopItemA (BOOL bCommonItem
,
127 LPCSTR lpIconLocation
,
129 LPCSTR lpWorkingDirectory
,
133 DPRINT1 ("AddDesktopItemA() not implemented!\n");
139 AddDesktopItemW (BOOL bCommonDesktop
,
142 LPCWSTR lpIconLocation
,
144 LPCWSTR lpWorkingDirectory
,
149 WCHAR szLinkPath
[MAX_PATH
];
150 WCHAR szArguments
[MAX_PATH
];
151 WCHAR szCommand
[MAX_PATH
];
152 WIN32_FIND_DATA FindData
;
161 DPRINT ("AddDesktopItemW() called\n");
165 if (!GetDesktopPath (bCommonDesktop
, szLinkPath
))
167 DPRINT1 ("GetDesktopPath() failed\n");
170 DPRINT ("Desktop path: '%S'\n", szLinkPath
);
172 /* Make sure the path exists */
173 hFind
= FindFirstFileW (szLinkPath
,
175 if (hFind
== INVALID_HANDLE_VALUE
)
177 DPRINT ("'%S' does not exist\n", szLinkPath
);
179 /* Create directory path */
180 if (!CreateDirectoryPath (szLinkPath
, NULL
))
185 DPRINT ("'%S' exists\n", szLinkPath
);
189 /* Append backslash, item name and ".lnk" extension */
190 wcscat (szLinkPath
, L
"\\");
191 wcscat (szLinkPath
, lpItemName
);
192 wcscat (szLinkPath
, L
".lnk");
193 DPRINT ("Link path: '%S'\n", szLinkPath
);
195 /* Split 'lpArguments' string into command and arguments */
196 Ptr
= wcschr (lpArguments
, L
' ');
197 DPRINT ("Ptr %p lpArguments %p\n", Ptr
, lpArguments
);
200 dwLength
= (DWORD
)(Ptr
- lpArguments
);
201 DPRINT ("dwLength %lu\n", dwLength
);
202 memcpy (szCommand
, lpArguments
, dwLength
* sizeof(WCHAR
));
203 szCommand
[dwLength
] = 0;
205 wcscpy (szArguments
, Ptr
);
209 wcscpy (szCommand
, lpArguments
);
212 DPRINT ("szCommand: '%S'\n", szCommand
);
213 DPRINT ("szArguments: '%S'\n", szArguments
);
215 /* dynamically load ole32.dll */
216 if(!LoadDynamicImports(&DynOle32
, &Ole32
))
218 DPRINT1("USERENV: Unable to load OLE32.DLL\n");
222 Ole32
.fn
.CoInitialize(NULL
);
224 hr
= Ole32
.fn
.CoCreateInstance(&CLSID_ShellLink
,
226 CLSCTX_INPROC_SERVER
,
231 Ole32
.fn
.CoUninitialize();
232 UnloadDynamicImports(&Ole32
);
236 hr
= psl
->lpVtbl
->QueryInterface(psl
,
241 psl
->lpVtbl
->SetDescription(psl
,
244 psl
->lpVtbl
->SetPath(psl
,
247 psl
->lpVtbl
->SetArguments(psl
,
250 psl
->lpVtbl
->SetIconLocation(psl
,
254 if (lpWorkingDirectory
!= NULL
)
256 psl
->lpVtbl
->SetWorkingDirectory(psl
,
261 psl
->lpVtbl
->SetWorkingDirectory(psl
,
262 L
"%HOMEDRIVE%%HOMEPATH%");
265 psl
->lpVtbl
->SetHotkey(psl
,
268 psl
->lpVtbl
->SetShowCmd(psl
,
271 hr
= ppf
->lpVtbl
->Save(ppf
,
277 ppf
->lpVtbl
->Release(ppf
);
280 psl
->lpVtbl
->Release(psl
);
282 Ole32
.fn
.CoUninitialize();
284 UnloadDynamicImports(&Ole32
);
286 DPRINT ("AddDesktopItemW() done\n");
293 DeleteDesktopItemA (BOOL bCommonItem
,
296 DPRINT1 ("DeleteDesktopItemA() not implemented!\n");
302 DeleteDesktopItemW (BOOL bCommonItem
,
305 WCHAR szLinkPath
[MAX_PATH
];
307 DPRINT ("DeleteDesktopItemW() called\n");
309 if (!GetDesktopPath (bCommonItem
, szLinkPath
))
311 DPRINT1 ("GetDesktopPath() failed\n");
315 wcscat (szLinkPath
, L
"\\");
316 wcscat (szLinkPath
, lpItemName
);
317 wcscat (szLinkPath
, L
".lnk");
318 DPRINT ("Link path: '%S'\n", szLinkPath
);
320 return DeleteFile (szLinkPath
);
325 CreateGroupA (LPCSTR lpGroupName
,
328 DPRINT1 ("CreateGroupA() not implemented!\n");
334 CreateGroupW (LPCWSTR lpGroupName
,
337 WCHAR szGroupPath
[MAX_PATH
];
339 DPRINT1 ("CreateGroupW() called\n");
341 if (lpGroupName
== NULL
|| *lpGroupName
== 0)
344 if (!GetProgramsPath (bCommonGroup
, szGroupPath
))
346 DPRINT1 ("GetProgramsPath() failed\n");
349 DPRINT1 ("Programs path: '%S'\n", szGroupPath
);
351 wcscat (szGroupPath
, L
"\\");
352 wcscat (szGroupPath
, lpGroupName
);
353 DPRINT1 ("Group path: '%S'\n", szGroupPath
);
355 /* Create directory path */
356 if (!CreateDirectoryPath (szGroupPath
, NULL
))
359 /* FIXME: Notify the shell */
361 DPRINT1 ("CreateGroupW() done\n");
368 DeleteGroupA (LPCSTR lpGroupName
,
371 DPRINT1 ("DeleteGroupA() not implemented!\n");
377 DeleteGroupW (LPCWSTR lpGroupName
,
380 WCHAR szGroupPath
[MAX_PATH
];
382 DPRINT ("DeleteGroupW() called\n");
384 if (lpGroupName
== NULL
|| *lpGroupName
== 0)
387 if (!GetProgramsPath (bCommonGroup
, szGroupPath
))
389 DPRINT1 ("GetProgramsPath() failed\n");
392 DPRINT ("Programs path: '%S'\n", szGroupPath
);
394 wcscat (szGroupPath
, L
"\\");
395 wcscat (szGroupPath
, lpGroupName
);
396 DPRINT ("Group path: '%S'\n", szGroupPath
);
398 /* Remove directory path */
399 if (!RemoveDirectoryPath (szGroupPath
))
402 /* FIXME: Notify the shell */
404 DPRINT ("DeleteGroupW() done\n");
411 AddItemA (LPCSTR lpGroupName
,
415 LPCSTR lpIconLocation
,
417 LPCSTR lpWorkingDirectory
,
421 DPRINT1 ("AddItemA() not implemented!\n");
427 AddItemW (LPCWSTR lpGroupName
,
431 LPCWSTR lpIconLocation
,
433 LPCWSTR lpWorkingDirectory
,
438 WCHAR szLinkPath
[MAX_PATH
];
439 WCHAR szArguments
[MAX_PATH
];
440 WCHAR szCommand
[MAX_PATH
];
441 WIN32_FIND_DATA FindData
;
450 DPRINT ("AddItemW() called\n");
454 if (!GetProgramsPath (bCommonGroup
, szLinkPath
))
456 DPRINT1 ("GetProgramsPath() failed\n");
460 DPRINT ("Programs path: '%S'\n", szLinkPath
);
462 if (lpGroupName
!= NULL
&& *lpGroupName
!= 0)
464 wcscat (szLinkPath
, L
"\\");
465 wcscat (szLinkPath
, lpGroupName
);
467 /* Make sure the path exists */
468 hFind
= FindFirstFileW (szLinkPath
,
470 if (hFind
== INVALID_HANDLE_VALUE
)
472 DPRINT ("'%S' does not exist\n", szLinkPath
);
473 if (!CreateGroupW (lpGroupName
,
479 DPRINT ("'%S' exists\n", szLinkPath
);
484 wcscat (szLinkPath
, L
"\\");
485 wcscat (szLinkPath
, lpItemName
);
486 wcscat (szLinkPath
, L
".lnk");
487 DPRINT ("Link path: '%S'\n", szLinkPath
);
489 /* Split 'lpArguments' string into command and arguments */
490 Ptr
= wcschr (lpArguments
, L
' ');
491 DPRINT ("Ptr %p lpArguments %p\n", Ptr
, lpArguments
);
494 dwLength
= (DWORD
)(Ptr
- lpArguments
);
495 DPRINT ("dwLength %lu\n", dwLength
);
496 memcpy (szCommand
, lpArguments
, dwLength
* sizeof(WCHAR
));
497 szCommand
[dwLength
] = 0;
499 wcscpy (szArguments
, Ptr
);
503 wcscpy (szCommand
, lpArguments
);
506 DPRINT ("szCommand: '%S'\n", szCommand
);
507 DPRINT ("szArguments: '%S'\n", szArguments
);
509 /* dynamically load ole32.dll */
510 if(!LoadDynamicImports(&DynOle32
, &Ole32
))
512 DPRINT1("USERENV: Unable to load OLE32.DLL\n");
516 Ole32
.fn
.CoInitialize(NULL
);
518 hr
= Ole32
.fn
.CoCreateInstance(&CLSID_ShellLink
,
520 CLSCTX_INPROC_SERVER
,
525 Ole32
.fn
.CoUninitialize();
526 UnloadDynamicImports(&Ole32
);
530 hr
= psl
->lpVtbl
->QueryInterface(psl
,
535 psl
->lpVtbl
->SetDescription(psl
,
538 psl
->lpVtbl
->SetPath(psl
,
541 psl
->lpVtbl
->SetArguments(psl
,
544 psl
->lpVtbl
->SetIconLocation(psl
,
548 if (lpWorkingDirectory
!= NULL
)
550 psl
->lpVtbl
->SetWorkingDirectory(psl
,
555 psl
->lpVtbl
->SetWorkingDirectory(psl
,
556 L
"%HOMEDRIVE%%HOMEPATH%");
559 psl
->lpVtbl
->SetHotkey(psl
,
562 psl
->lpVtbl
->SetShowCmd(psl
,
565 hr
= ppf
->lpVtbl
->Save(ppf
,
571 ppf
->lpVtbl
->Release(ppf
);
574 psl
->lpVtbl
->Release(psl
);
576 Ole32
.fn
.CoUninitialize();
577 UnloadDynamicImports(&Ole32
);
579 DPRINT ("AddItemW() done\n");
586 DeleteItemA (LPCSTR lpGroupName
,
591 DPRINT1 ("DeleteItemA() not implemented!\n");
597 DeleteItemW (LPCWSTR lpGroupName
,
602 WCHAR szItemPath
[MAX_PATH
];
605 DPRINT ("DeleteItemW() called\n");
607 if (!GetProgramsPath (bCommonGroup
, szItemPath
))
609 DPRINT1 ("GetProgramsPath() failed\n");
612 DPRINT ("Programs path: '%S'\n", szItemPath
);
614 if (lpGroupName
!= NULL
&& *lpGroupName
!= 0)
616 wcscat (szItemPath
, L
"\\");
617 wcscat (szItemPath
, lpGroupName
);
620 wcscat (szItemPath
, L
"\\");
621 wcscat (szItemPath
, lpItemName
);
622 wcscat (szItemPath
, L
".lnk");
623 DPRINT ("Item path: '%S'\n", szItemPath
);
625 if (!DeleteFileW (szItemPath
))
628 /* FIXME: Notify the shell */
632 Ptr
= wcsrchr (szItemPath
, L
'\\');
637 DPRINT ("Item path: '%S'\n", szItemPath
);
638 if (RemoveDirectoryW (szItemPath
))
640 /* FIXME: Notify the shell */
644 DPRINT ("DeleteItemW() done\n");