wix-msi-installer-20040620
[openafs.git] / src / WINNT / install / wix / custom / renameconnection.cpp
1 #include <afx.h>
2 #include <windows.h>
3 #include <shellapi.h>
4 #include <objbase.h>
5 #include <shlobj.h>
6 #include <wtypes.h>
7
8 #define NETSHELL_LIBRARY _T("netshell.dll")
9
10 // Use the IShellFolder API to rename the connection.
11 static HRESULT rename_shellfolder(PCWSTR wGuid, PCWSTR wNewName)
12 {
13     // This is the GUID for the network connections folder. It is constant.
14     // {7007ACC7-3202-11D1-AAD2-00805FC1270E}
15     const GUID CLSID_NetworkConnections = {
16         0x7007ACC7, 0x3202, 0x11D1, {
17             0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E
18         }
19     };
20     LPITEMIDLIST pidl;
21     IShellFolder *pShellFolder;
22     IMalloc *pShellMalloc;
23
24     // Build the display name in the form "::{GUID}".
25     if (wcslen(wGuid) >= MAX_PATH)
26         return E_INVALIDARG;
27     WCHAR szAdapterGuid[MAX_PATH + 2];
28     swprintf(szAdapterGuid, L"::%ls", wGuid);
29
30     // Initialize COM.
31     CoInitialize(NULL);
32
33     // Get the shell allocator.
34     HRESULT hr = SHGetMalloc(&pShellMalloc);
35     if (SUCCEEDED(hr))
36     {
37         // Create an instance of the network connections folder.
38         hr = CoCreateInstance(CLSID_NetworkConnections, NULL,
39                               CLSCTX_INPROC_SERVER, IID_IShellFolder,
40                               reinterpret_cast<LPVOID *>(&pShellFolder));
41     }
42     // Parse the display name.
43     if (SUCCEEDED(hr))
44     {
45         hr = pShellFolder->ParseDisplayName(NULL, NULL, szAdapterGuid, NULL,
46                                             &pidl, NULL);
47     }
48     if (SUCCEEDED(hr))
49     {
50         hr = pShellFolder->SetNameOf(NULL, pidl, wNewName, SHGDN_NORMAL,
51                                      &pidl);
52         pShellMalloc->Free(pidl);
53     }
54     CoUninitialize();
55     return hr;
56 }
57
58 extern "C" int RenameConnection(PCWSTR GuidString, PCWSTR NewName)
59 {
60     typedef HRESULT (WINAPI *lpHrRenameConnection)(const GUID *, PCWSTR);
61     lpHrRenameConnection RenameConnectionFunc = NULL;
62     HRESULT status;
63
64     // First try the IShellFolder interface, which was unimplemented
65     // for the network connections folder before XP.
66     status = rename_shellfolder(GuidString, NewName);
67     if (status == E_NOTIMPL)
68     {
69         // The IShellFolder interface is not implemented on this platform.
70         // Try the (undocumented) HrRenameConnection API in the netshell
71         // library.
72         CLSID clsid;
73         HINSTANCE hNetShell;
74         status = CLSIDFromString((LPOLESTR) GuidString, &clsid);
75         if (FAILED(status))
76             return -1;
77         hNetShell = LoadLibrary(NETSHELL_LIBRARY);
78         if (hNetShell == NULL)
79             return -1;
80         RenameConnectionFunc =
81           (lpHrRenameConnection) GetProcAddress(hNetShell,
82                                                 "HrRenameConnection");
83         if (RenameConnectionFunc == NULL)
84         {
85             FreeLibrary(hNetShell);
86             return -1;
87         }
88         status = RenameConnectionFunc(&clsid, NewName);
89         FreeLibrary(hNetShell);
90     }
91     if (FAILED(status))
92         return -1;
93     return 0;
94 }