/*
 *  ReactOS kernel
 *  Copyright (C) 2004 ReactOS Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
/*
 * COPYRIGHT:       See COPYING in the top level directory
 * PROJECT:         ReactOS system libraries
 * FILE:            dll/win32/userenv/desktop.c
 * PURPOSE:         Desktop and start menu support functions.
 * PROGRAMMER:      Eric Kohl
 */

#include "precomp.h"

#include <shlobj.h>

#define NDEBUG
#include <debug.h>

/* FUNCTIONS ***************************************************************/

static
BOOL
GetDesktopPath(BOOL bCommonPath,
               LPWSTR lpDesktopPath)
{
    WCHAR szPath[MAX_PATH];
    DWORD dwLength;
    DWORD dwType;
    HKEY hKey;
    LONG Error;

    DPRINT("GetDesktopPath() called\n");

    Error = RegOpenKeyExW(HKEY_CURRENT_USER,
                          L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
                          0,
                          KEY_QUERY_VALUE,
                          &hKey);
    if (Error != ERROR_SUCCESS)
    {
        DPRINT1("RegOpenKeyExW() failed\n");
        SetLastError((DWORD)Error);
        return FALSE;
    }

    dwLength = MAX_PATH * sizeof(WCHAR);
    Error = RegQueryValueExW(hKey,
                             bCommonPath ? L"Common Desktop" : L"Desktop",
                             0,
                             &dwType,
                             (LPBYTE)szPath,
                             &dwLength);
    if (Error != ERROR_SUCCESS)
    {
        DPRINT1("RegQueryValueExW() failed\n");
        RegCloseKey(hKey);
        SetLastError((DWORD)Error);
        return FALSE;
    }

    RegCloseKey(hKey);

    if (dwType == REG_EXPAND_SZ)
    {
        ExpandEnvironmentStringsW(szPath,
                                  lpDesktopPath,
                                  MAX_PATH);
    }
    else
    {
        wcscpy(lpDesktopPath, szPath);
    }

    DPRINT("GetDesktopPath() done\n");

    return TRUE;
}


static
BOOL
GetProgramsPath(BOOL bCommonPath,
                LPWSTR lpProgramsPath)
{
    WCHAR szPath[MAX_PATH];
    DWORD dwLength;
    DWORD dwType;
    HKEY hKey;
    LONG Error;

    DPRINT("GetProgramsPath() called\n");

    Error = RegOpenKeyExW(HKEY_CURRENT_USER,
                          L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
                          0,
                          KEY_QUERY_VALUE,
                          &hKey);
    if (Error != ERROR_SUCCESS)
    {
        DPRINT1("RegOpenKeyExW() failed\n");
        SetLastError((DWORD)Error);
        return FALSE;
    }

    dwLength = MAX_PATH * sizeof(WCHAR);
    Error = RegQueryValueExW(hKey,
                             bCommonPath ? L"Common Programs" : L"Programs",
                             0,
                             &dwType,
                             (LPBYTE)szPath,
                             &dwLength);
    if (Error != ERROR_SUCCESS)
    {
        DPRINT1("RegQueryValueExW() failed\n");
        RegCloseKey(hKey);
        SetLastError((DWORD)Error);
        return FALSE;
    }

    RegCloseKey(hKey);

    if (dwType == REG_EXPAND_SZ)
    {
        ExpandEnvironmentStringsW(szPath,
                                  lpProgramsPath,
                                  MAX_PATH);
    }
    else
    {
        wcscpy(lpProgramsPath,
               szPath);
    }

    DPRINT("GetProgramsPath() done\n");

    return TRUE;
}


BOOL
WINAPI
AddDesktopItemA(BOOL bCommonItem,
                LPCSTR lpItemName,
                LPCSTR lpArguments,
                LPCSTR lpIconLocation,
                INT iIcon,
                LPCSTR lpWorkingDirectory, /* Optional */
                WORD wHotKey,
                INT iShowCmd)
{
    UNICODE_STRING ItemName;
    UNICODE_STRING Arguments;
    UNICODE_STRING IconLocation;
    UNICODE_STRING WorkingDirectory;
    BOOL bResult;

    if (!RtlCreateUnicodeStringFromAsciiz(&ItemName,
                                          (LPSTR)lpItemName))
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    if (!RtlCreateUnicodeStringFromAsciiz(&Arguments,
                                          (LPSTR)lpArguments))
    {
        RtlFreeUnicodeString(&ItemName);
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    if (!RtlCreateUnicodeStringFromAsciiz(&IconLocation,
                                          (LPSTR)lpIconLocation))
    {
        RtlFreeUnicodeString(&Arguments);
        RtlFreeUnicodeString(&ItemName);
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    if (lpWorkingDirectory != NULL)
    {
        if (!RtlCreateUnicodeStringFromAsciiz(&WorkingDirectory,
                                              (LPSTR)lpWorkingDirectory))
        {
            RtlFreeUnicodeString(&IconLocation);
            RtlFreeUnicodeString(&Arguments);
            RtlFreeUnicodeString(&ItemName);
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
    }

    bResult = AddDesktopItemW(bCommonItem,
                              ItemName.Buffer,
                              Arguments.Buffer,
                              IconLocation.Buffer,
                              iIcon,
                              (lpWorkingDirectory != NULL) ? WorkingDirectory.Buffer : NULL,
                              wHotKey,
                              iShowCmd);

    if (lpWorkingDirectory != NULL)
    {
        RtlFreeUnicodeString(&WorkingDirectory);
    }

    RtlFreeUnicodeString(&IconLocation);
    RtlFreeUnicodeString(&Arguments);
    RtlFreeUnicodeString(&ItemName);

    return bResult;
}


BOOL
WINAPI
AddDesktopItemW(BOOL bCommonDesktop,
                LPCWSTR lpItemName,
                LPCWSTR lpArguments,
                LPCWSTR lpIconLocation,
                INT iIcon,
                LPCWSTR lpWorkingDirectory,  /* Optional */
                WORD wHotKey,
                INT iShowCmd)
{
    DYN_FUNCS Ole32;
    WCHAR szLinkPath[MAX_PATH];
    WCHAR szArguments[MAX_PATH];
    WCHAR szCommand[MAX_PATH];
    WIN32_FIND_DATAW FindData;
    HANDLE hFind;
    LPWSTR Ptr;
    DWORD dwLength;
    IShellLinkW* psl;
    IPersistFile* ppf;
    HRESULT hr;
    BOOL bResult;

    DPRINT("AddDesktopItemW() called\n");

    bResult = FALSE;

    if (!GetDesktopPath(bCommonDesktop, szLinkPath))
    {
        DPRINT1("GetDesktopPath() failed\n");
        return FALSE;
    }
    DPRINT("Desktop path: '%S'\n", szLinkPath);

    /* Make sure the path exists */
    hFind = FindFirstFileW(szLinkPath,
                           &FindData);
    if (hFind == INVALID_HANDLE_VALUE)
    {
        DPRINT("'%S' does not exist\n", szLinkPath);

        /* Create directory path */
        if (!CreateDirectoryPath(szLinkPath, NULL))
            return FALSE;
    }
    else
    {
        DPRINT("'%S' exists\n", szLinkPath);
        FindClose(hFind);
    }

    /* Append backslash, item name and ".lnk" extension */
    wcscat(szLinkPath, L"\\");
    wcscat(szLinkPath, lpItemName);
    wcscat(szLinkPath, L".lnk");
    DPRINT("Link path: '%S'\n", szLinkPath);

    /* Split 'lpArguments' string into command and arguments */
    Ptr = wcschr(lpArguments, L' ');
    DPRINT("Ptr %p  lpArguments %p\n", Ptr, lpArguments);
    if (Ptr != NULL)
    {
        dwLength = (DWORD)(Ptr - lpArguments);
        DPRINT("dwLength %lu\n", dwLength);
        memcpy(szCommand, lpArguments, dwLength * sizeof(WCHAR));
        szCommand[dwLength] = 0;
        Ptr++;
        wcscpy(szArguments, Ptr);
    }
    else
    {
        wcscpy(szCommand, lpArguments);
        szArguments[0] = 0;
    }
    DPRINT("szCommand: '%S'\n", szCommand);
    DPRINT("szArguments: '%S'\n", szArguments);

    /* Dynamically load ole32.dll */
    if (!LoadDynamicImports(&DynOle32, &Ole32))
    {
        DPRINT1("USERENV: Unable to load OLE32.DLL\n");
        return FALSE;
    }

    Ole32.fn.CoInitialize(NULL);

    hr = Ole32.fn.CoCreateInstance(&CLSID_ShellLink,
                                   NULL,
                                   CLSCTX_INPROC_SERVER,
                                   &IID_IShellLinkW,
                                   (LPVOID*)&psl);
    if (!SUCCEEDED(hr))
    {
        Ole32.fn.CoUninitialize();
        UnloadDynamicImports(&Ole32);
        return FALSE;
    }

    hr = psl->lpVtbl->QueryInterface(psl,
                                     &IID_IPersistFile,
                                     (LPVOID*)&ppf);
    if (SUCCEEDED(hr))
    {
        psl->lpVtbl->SetDescription(psl,
                                    lpItemName);

        psl->lpVtbl->SetPath(psl,
                             szCommand);

        psl->lpVtbl->SetArguments(psl,
                                  szArguments);

        psl->lpVtbl->SetIconLocation(psl,
                                     lpIconLocation,
                                     iIcon);

        if (lpWorkingDirectory != NULL)
        {
            psl->lpVtbl->SetWorkingDirectory(psl,
                                             lpWorkingDirectory);
        }
        else
        {
            psl->lpVtbl->SetWorkingDirectory(psl,
                                             L"%HOMEDRIVE%%HOMEPATH%");
        }

        psl->lpVtbl->SetHotkey(psl,
                               wHotKey);

        psl->lpVtbl->SetShowCmd(psl,
                                iShowCmd);

        hr = ppf->lpVtbl->Save(ppf,
                               szLinkPath,
                               TRUE);
        if (SUCCEEDED(hr))
            bResult = TRUE;

        ppf->lpVtbl->Release(ppf);
    }

    psl->lpVtbl->Release(psl);

    Ole32.fn.CoUninitialize();

    UnloadDynamicImports(&Ole32);

    DPRINT("AddDesktopItemW() done\n");

    return bResult;
}


BOOL
WINAPI
DeleteDesktopItemA(BOOL bCommonItem,
                   LPCSTR lpItemName)
{
    UNICODE_STRING ItemName;
    BOOL bResult;

    if (!RtlCreateUnicodeStringFromAsciiz(&ItemName,
                                          (LPSTR)lpItemName))
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    bResult = DeleteDesktopItemW(bCommonItem,
                                 ItemName.Buffer);

    RtlFreeUnicodeString(&ItemName);

    return bResult;
}


BOOL
WINAPI
DeleteDesktopItemW(BOOL bCommonItem,
                   LPCWSTR lpItemName)
{
    WCHAR szLinkPath[MAX_PATH];

    DPRINT("DeleteDesktopItemW() called\n");

    if (!GetDesktopPath(bCommonItem, szLinkPath))
    {
        DPRINT1("GetDesktopPath() failed\n");
        return FALSE;
    }

    wcscat(szLinkPath, L"\\");
    wcscat(szLinkPath, lpItemName);
    wcscat(szLinkPath, L".lnk");
    DPRINT("Link path: '%S'\n", szLinkPath);

    return DeleteFileW (szLinkPath);
}


BOOL
WINAPI
CreateGroupA(LPCSTR lpGroupName,
             BOOL bCommonGroup)
{
    UNICODE_STRING GroupName;
    BOOL bResult;

    if (!RtlCreateUnicodeStringFromAsciiz(&GroupName,
                                          (LPSTR)lpGroupName))
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    bResult = CreateGroupW(GroupName.Buffer, bCommonGroup);

    RtlFreeUnicodeString(&GroupName);

    return bResult;
}


BOOL
WINAPI
CreateGroupW(LPCWSTR lpGroupName,
             BOOL bCommonGroup)
{
    WCHAR szGroupPath[MAX_PATH];

    DPRINT1("CreateGroupW() called\n");

    if (lpGroupName == NULL || *lpGroupName == 0)
        return TRUE;

    if (!GetProgramsPath(bCommonGroup, szGroupPath))
    {
        DPRINT1("GetProgramsPath() failed\n");
        return FALSE;
    }
    DPRINT1("Programs path: '%S'\n", szGroupPath);

    wcscat(szGroupPath, L"\\");
    wcscat(szGroupPath, lpGroupName);
    DPRINT1("Group path: '%S'\n", szGroupPath);

    /* Create directory path */
    if (!CreateDirectoryPath (szGroupPath, NULL))
        return FALSE;

    /* FIXME: Notify the shell */

    DPRINT1("CreateGroupW() done\n");

    return TRUE;
}


BOOL
WINAPI
DeleteGroupA(LPCSTR lpGroupName,
             BOOL bCommonGroup)
{
    UNICODE_STRING GroupName;
    BOOL bResult;

    if (!RtlCreateUnicodeStringFromAsciiz(&GroupName,
                                          (LPSTR)lpGroupName))
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    bResult = DeleteGroupW(GroupName.Buffer, bCommonGroup);

    RtlFreeUnicodeString(&GroupName);

    return bResult;
}


BOOL
WINAPI
DeleteGroupW(LPCWSTR lpGroupName,
             BOOL bCommonGroup)
{
    WCHAR szGroupPath[MAX_PATH];

    DPRINT("DeleteGroupW() called\n");

    if (lpGroupName == NULL || *lpGroupName == 0)
        return TRUE;

    if (!GetProgramsPath(bCommonGroup, szGroupPath))
    {
        DPRINT1("GetProgramsPath() failed\n");
        return FALSE;
    }
    DPRINT("Programs path: '%S'\n", szGroupPath);

    wcscat(szGroupPath, L"\\");
    wcscat(szGroupPath, lpGroupName);
    DPRINT("Group path: '%S'\n", szGroupPath);

    /* Remove directory path */
    if (!RemoveDirectoryPath (szGroupPath))
        return FALSE;

    /* FIXME: Notify the shell */

    DPRINT("DeleteGroupW() done\n");

    return TRUE;
}


BOOL
WINAPI
AddItemA(LPCSTR lpGroupName,  /* Optional */
         BOOL bCommonGroup,
         LPCSTR lpItemName,
         LPCSTR lpArguments,
         LPCSTR lpIconLocation,
         INT iIcon,
         LPCSTR lpWorkingDirectory,  /* Optional */
         WORD wHotKey,
         INT iShowCmd)
{
    UNICODE_STRING GroupName;
    UNICODE_STRING ItemName;
    UNICODE_STRING Arguments;
    UNICODE_STRING IconLocation;
    UNICODE_STRING WorkingDirectory;
    BOOL bResult;

    if (!RtlCreateUnicodeStringFromAsciiz(&ItemName,
                                          (LPSTR)lpItemName))
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    if (!RtlCreateUnicodeStringFromAsciiz(&Arguments,
                                          (LPSTR)lpArguments))
    {
        RtlFreeUnicodeString(&ItemName);
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    if (!RtlCreateUnicodeStringFromAsciiz(&IconLocation,
                                          (LPSTR)lpIconLocation))
    {
        RtlFreeUnicodeString(&Arguments);
        RtlFreeUnicodeString(&ItemName);
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    if (lpGroupName != NULL)
    {
        if (!RtlCreateUnicodeStringFromAsciiz(&GroupName,
                                              (LPSTR)lpGroupName))
        {
            RtlFreeUnicodeString(&IconLocation);
            RtlFreeUnicodeString(&Arguments);
            RtlFreeUnicodeString(&ItemName);
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
    }

    if (lpWorkingDirectory != NULL)
    {
        if (!RtlCreateUnicodeStringFromAsciiz(&WorkingDirectory,
                                              (LPSTR)lpWorkingDirectory))
        {
            if (lpGroupName != NULL)
            {
                RtlFreeUnicodeString(&GroupName);
            }
            RtlFreeUnicodeString(&IconLocation);
            RtlFreeUnicodeString(&Arguments);
            RtlFreeUnicodeString(&ItemName);
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
    }

    bResult = AddItemW((lpGroupName != NULL) ? GroupName.Buffer : NULL,
                       bCommonGroup,
                       ItemName.Buffer,
                       Arguments.Buffer,
                       IconLocation.Buffer,
                       iIcon,
                       (lpWorkingDirectory != NULL) ? WorkingDirectory.Buffer : NULL,
                       wHotKey,
                       iShowCmd);

    if (lpGroupName != NULL)
    {
        RtlFreeUnicodeString(&GroupName);
    }

    if (lpWorkingDirectory != NULL)
    {
        RtlFreeUnicodeString(&WorkingDirectory);
    }

    RtlFreeUnicodeString(&IconLocation);
    RtlFreeUnicodeString(&Arguments);
    RtlFreeUnicodeString(&ItemName);

    return bResult;
}


BOOL
WINAPI
AddItemW(LPCWSTR lpGroupName,  /* Optional */
         BOOL bCommonGroup,
         LPCWSTR lpItemName,
         LPCWSTR lpArguments,
         LPCWSTR lpIconLocation,
         INT iIcon,
         LPCWSTR lpWorkingDirectory,  /* Optional */
         WORD wHotKey,
         INT iShowCmd)
{
    DYN_FUNCS Ole32;
    WCHAR szLinkPath[MAX_PATH];
    WCHAR szArguments[MAX_PATH];
    WCHAR szCommand[MAX_PATH];
    WIN32_FIND_DATAW FindData;
    HANDLE hFind;
    LPWSTR Ptr;
    DWORD dwLength;
    IShellLinkW* psl;
    IPersistFile* ppf;
    HRESULT hr;
    BOOL bResult;

    DPRINT("AddItemW() called\n");

    bResult = FALSE;

    if (!GetProgramsPath(bCommonGroup, szLinkPath))
    {
        DPRINT1("GetProgramsPath() failed\n");
        return FALSE;
    }

    DPRINT("Programs path: '%S'\n", szLinkPath);

    if (lpGroupName != NULL && *lpGroupName != 0)
    {
        wcscat(szLinkPath, L"\\");
        wcscat(szLinkPath, lpGroupName);

        /* Make sure the path exists */
        hFind = FindFirstFileW(szLinkPath,
                               &FindData);
        if (hFind == INVALID_HANDLE_VALUE)
        {
            DPRINT("'%S' does not exist\n", szLinkPath);
            if (!CreateGroupW(lpGroupName,
                              bCommonGroup))
                return FALSE;
        }
        else
        {
            DPRINT("'%S' exists\n", szLinkPath);
            FindClose(hFind);
        }
    }

    wcscat(szLinkPath, L"\\");
    wcscat(szLinkPath, lpItemName);
    wcscat(szLinkPath, L".lnk");
    DPRINT("Link path: '%S'\n", szLinkPath);

    /* Split 'lpArguments' string into command and arguments */
    Ptr = wcschr(lpArguments, L' ');
    DPRINT("Ptr %p  lpArguments %p\n", Ptr, lpArguments);
    if (Ptr != NULL)
    {
        dwLength = (DWORD)(Ptr - lpArguments);
        DPRINT("dwLength %lu\n", dwLength);
        memcpy(szCommand, lpArguments, dwLength * sizeof(WCHAR));
        szCommand[dwLength] = 0;
        Ptr++;
        wcscpy(szArguments, Ptr);
    }
    else
    {
        wcscpy(szCommand, lpArguments);
        szArguments[0] = 0;
    }
    DPRINT("szCommand: '%S'\n", szCommand);
    DPRINT("szArguments: '%S'\n", szArguments);

    /* Dynamically load ole32.dll */
    if (!LoadDynamicImports(&DynOle32, &Ole32))
    {
        DPRINT1("USERENV: Unable to load OLE32.DLL\n");
        return FALSE;
    }

    Ole32.fn.CoInitialize(NULL);

    hr = Ole32.fn.CoCreateInstance(&CLSID_ShellLink,
                                   NULL,
                                   CLSCTX_INPROC_SERVER,
                                   &IID_IShellLinkW,
                                   (LPVOID*)&psl);
    if (!SUCCEEDED(hr))
    {
        Ole32.fn.CoUninitialize();
        UnloadDynamicImports(&Ole32);
        return FALSE;
    }

    hr = psl->lpVtbl->QueryInterface(psl,
                                     &IID_IPersistFile,
                                     (LPVOID*)&ppf);
    if (SUCCEEDED(hr))
    {
        psl->lpVtbl->SetDescription(psl,
                                    lpItemName);

        psl->lpVtbl->SetPath(psl,
                             szCommand);

        psl->lpVtbl->SetArguments(psl,
                                  szArguments);

        psl->lpVtbl->SetIconLocation(psl,
                                     lpIconLocation,
                                     iIcon);

        if (lpWorkingDirectory != NULL)
        {
            psl->lpVtbl->SetWorkingDirectory(psl,
                                             lpWorkingDirectory);
        }
        else
        {
            psl->lpVtbl->SetWorkingDirectory(psl,
                                             L"%HOMEDRIVE%%HOMEPATH%");
        }

        psl->lpVtbl->SetHotkey(psl,
                               wHotKey);

        psl->lpVtbl->SetShowCmd(psl,
                                iShowCmd);

        hr = ppf->lpVtbl->Save(ppf,
                               szLinkPath,
                               TRUE);
        if (SUCCEEDED(hr))
            bResult = TRUE;

        ppf->lpVtbl->Release(ppf);
    }

    psl->lpVtbl->Release(psl);

    Ole32.fn.CoUninitialize();
    UnloadDynamicImports(&Ole32);

    DPRINT("AddItemW() done\n");

    return bResult;
}


BOOL
WINAPI
DeleteItemA(LPCSTR lpGroupName, /* Optional */
            BOOL bCommonGroup,
            LPCSTR lpItemName,
            BOOL bDeleteGroup)
{
    UNICODE_STRING GroupName;
    UNICODE_STRING ItemName;
    BOOL bResult;

    if (lpGroupName != NULL)
    {
        if (!RtlCreateUnicodeStringFromAsciiz(&GroupName,
                                              (LPSTR)lpGroupName))
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
    }

    if (!RtlCreateUnicodeStringFromAsciiz(&ItemName,
                                          (LPSTR)lpItemName))
    {
        if (lpGroupName != NULL)
        {
            RtlFreeUnicodeString(&GroupName);
        }

        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }

    bResult = DeleteItemW((lpGroupName != NULL) ? GroupName.Buffer : NULL,
                          bCommonGroup,
                          ItemName.Buffer,
                          bDeleteGroup);

    RtlFreeUnicodeString(&ItemName);
    if (lpGroupName != NULL)
    {
        RtlFreeUnicodeString(&GroupName);
    }

    return bResult;
}


BOOL
WINAPI
DeleteItemW(LPCWSTR lpGroupName, /* Optional */
            BOOL bCommonGroup,
            LPCWSTR lpItemName,
            BOOL bDeleteGroup)
{
    WCHAR szItemPath[MAX_PATH];
    LPWSTR Ptr;

    DPRINT("DeleteItemW() called\n");

    if (!GetProgramsPath(bCommonGroup, szItemPath))
    {
        DPRINT1("GetProgramsPath() failed\n");
        return FALSE;
    }
    DPRINT("Programs path: '%S'\n", szItemPath);

    if (lpGroupName != NULL && *lpGroupName != 0)
    {
        wcscat(szItemPath, L"\\");
        wcscat(szItemPath, lpGroupName);
    }

    wcscat(szItemPath, L"\\");
    wcscat(szItemPath, lpItemName);
    wcscat(szItemPath, L".lnk");
    DPRINT("Item path: '%S'\n", szItemPath);

    if (!DeleteFileW(szItemPath))
        return FALSE;

    /* FIXME: Notify the shell */

    if (bDeleteGroup)
    {
        Ptr = wcsrchr(szItemPath, L'\\');
        if (Ptr == NULL)
            return TRUE;

        *Ptr = 0;
        DPRINT("Item path: '%S'\n", szItemPath);
        if (RemoveDirectoryW(szItemPath))
        {
            /* FIXME: Notify the shell */
        }
    }

    DPRINT("DeleteItemW() done\n");

    return TRUE;
}

/* EOF */
