blesslnk.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. // blesslnk.cpp : Program to bless a LNK file with darwin descriptor
  2. // or logo3 app name/id
  3. #include <tchar.h>
  4. #include <stdio.h>
  5. #include <windows.h>
  6. #include <shlobj.h>
  7. #include <shlguidp.h>
  8. #include <shlwapi.h>
  9. #include "cdfsubs.hpp"
  10. #include "resource.h"
  11. #define FAIL_ARGS       1
  12. #define FAIL_OLE        2
  13. #define FAIL_LOAD       3
  14. #define FAIL_ENTRY      4
  15. #define FAIL_REG        5
  16. #define FAIL_SHELL      6
  17. #define DARWIN_ID       0x1
  18. #define LOGO3_ID        0x2
  19. // The following strings are used to support the shell link set path feature that
  20. // allows us to bless links for Darwin or Logo3 publising support in IE4
  21. #define DARWINGUID_TAG TEXT("::{9db1186e-40df-11d1-aa8c-00c04fb67863}:")
  22. #define DARWIN_TAG_LEN (ARRAYSIZE(DARWINGUID_TAG)-1)
  23. #define LOGO3GUID_TAG  TEXT("::{9db1186f-40df-11d1-aa8c-00c04fb67863}:")
  24. #define LOGO3_TAG_LEN  (ARRAYSIZE(LOGO3GUID_TAG)-1)
  25. // checking for shell32 4.72.2106.0 or greater
  26. #define IE401_SHELL_MAJOR               0x0004
  27. #define IE401_SHELL_MINOR               0x48
  28. #define IE401_SHELL_BUILD               0x083a
  29. BOOL IE401ShellAvailable()
  30. {
  31.         BOOL bCanBlessLink = FALSE;
  32.         DLLGETVERSIONPROC lpfnVersionProc = NULL;
  33.         DLLVERSIONINFO dlinfo;
  34.         HMODULE hMod = LoadLibrary("shell32.dll");
  35.         if (hMod) {
  36.                 if ( (lpfnVersionProc = (DLLGETVERSIONPROC)GetProcAddress(hMod,"DllGetVersion")) ) 
  37.                 {
  38.                         dlinfo.cbSize = sizeof(DLLVERSIONINFO);
  39.                         if ( (lpfnVersionProc(&dlinfo) == S_OK) &&
  40.                             (dlinfo.dwMajorVersion > IE401_SHELL_MAJOR) ||
  41.                                 ((dlinfo.dwMajorVersion == IE401_SHELL_MAJOR) &&
  42.                                  (dlinfo.dwMinorVersion >= IE401_SHELL_MINOR)
  43.                                 ))
  44.                         {
  45.                                 bCanBlessLink = TRUE;
  46.                                 if (dlinfo.dwMajorVersion == IE401_SHELL_MAJOR &&
  47.                                     dlinfo.dwMinorVersion == IE401_SHELL_MINOR &&
  48.                                     dlinfo.dwBuildNumber < IE401_SHELL_BUILD)
  49.                                 {
  50.                                         bCanBlessLink = FALSE;
  51.                                 }
  52.                                         
  53.                         }
  54.                 }
  55.         }
  56.         if (hMod)
  57.                 FreeLibrary(hMod);
  58.         return bCanBlessLink;
  59. }
  60. HRESULT SetLnkBlessing( IShellLink *pishl, DWORD dwSig, LPSTR szBlessing )
  61. {
  62.     HRESULT hr = S_OK;
  63.     char szPath[MAX_PATH*4];
  64.         char szTarget[MAX_PATH];
  65.         if (dwSig == DARWIN_ID) {
  66.                 lstrcpy(szPath, DARWINGUID_TAG);
  67.         } else if (dwSig == LOGO3_ID) {
  68.                 lstrcpy(szPath, LOGO3GUID_TAG);
  69.         }else {
  70.                 hr = E_INVALIDARG;
  71.         }
  72.         if (SUCCEEDED(hr)) {
  73.                 lstrcat(szPath, szBlessing);
  74.                 lstrcat(szPath, "::");
  75.                 // get real target
  76.                 hr = pishl->GetPath(szTarget, MAX_PATH, NULL,0);
  77.                 // copy real target name
  78.                 if (SUCCEEDED(hr)) {
  79.                         lstrcat(szPath, szTarget);
  80.                         hr = pishl->SetPath( szPath );
  81.                 }
  82.         }
  83.     return hr;
  84. }
  85. int __cdecl main(int argc, char * argv[])
  86. {
  87.     int             iReturn = 0;
  88.     HRESULT         hr = S_OK;
  89.     LPSTR           pszLnkName = NULL;
  90.     LPSTR           pszLogo3ID = NULL;
  91.     LPSTR           pszDarwinID = NULL;
  92.     LPSTR           pszCDFURL = NULL;
  93.     LPSTR           pszTok;
  94.     IPersistFile    *pipfLnk = NULL;
  95.     // Parse command line arguments.
  96.     int iTok;
  97.     for (iTok = 1; iTok < argc; iTok++)
  98.     {                                
  99.             pszTok = argv[iTok];
  100.             
  101.             if ((pszTok[0] == '-') || (pszTok[0] == '/'))
  102.             {
  103.                     switch (pszTok[1])
  104.                     {
  105.                     case 'c':
  106.                     case 'C':
  107.                             pszCDFURL = argv[iTok+1];
  108.                             iTok++;
  109.                             break;
  110.                     case 'l':
  111.                     case 'L':
  112.                             pszLogo3ID = argv[iTok+1];
  113.                             iTok++;
  114.                             break;
  115.                                                             
  116.                     case 'd':
  117.                     case 'D':
  118.                             pszDarwinID = argv[iTok+1];
  119.                             iTok++;
  120.                             break;
  121.                             
  122.                     case '?':
  123.                             fprintf(stderr, "nUsage: blesslnk [/l Logo3-ID] [/d Darwin-ID] lnknamen/l - bless for Logo3 Application Channel notifcation.n/d - bless for Darwinn" );
  124.                             break;
  125.                     default:
  126.                             fprintf(stderr, "err - unrecognized flag: %sn", pszTok);
  127.                             return FAIL_ARGS;
  128.                     }
  129.             }
  130.             else
  131.             {
  132.                     if (pszLnkName == NULL)
  133.                     {
  134.                             pszLnkName = pszTok;
  135.                             break;
  136.                     }
  137.                     else
  138.                     {
  139.                             fprintf(stderr, "err - extra argument: %sn", pszTok);
  140.                             return FAIL_ARGS;
  141.                     }
  142.             }
  143.     }
  144.     if (pszLnkName == NULL)
  145.     {
  146.             fprintf(stderr, "err - no lnk file specifiedn" );
  147.             return FAIL_ARGS;
  148.     }
  149.     if (!IE401ShellAvailable()) 
  150.     {
  151.             fprintf(stderr, "err - Need to have IE401 shell enabled for this feature.n" );
  152.             return FAIL_SHELL;
  153.     }
  154.     // Initialize OLE.                              
  155.     if (FAILED(CoInitialize(NULL)))
  156.     {
  157.             return FAIL_OLE;
  158.     }
  159.     if ( SUCCEEDED(hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IPersistFile, (LPVOID*)&pipfLnk)) )
  160.     {
  161.         WCHAR szwLnkName[MAX_PATH];
  162.         MultiByteToWideChar( CP_ACP, 0, pszLnkName, -1, szwLnkName, MAX_PATH );
  163.         if ( SUCCEEDED(hr = pipfLnk->Load(szwLnkName, STGM_READ)) )
  164.         {
  165.             IShellLink *pishl = NULL;
  166.             if ( SUCCEEDED(hr = pipfLnk->QueryInterface(IID_IShellLink, (LPVOID*)&pishl)) )
  167.                         {
  168.                     if ( pszLogo3ID )
  169.                     {
  170.                         if ( FAILED(hr = SetLnkBlessing( pishl, LOGO3_ID, pszLogo3ID )) )
  171.                             fprintf( stderr, "err - failed to bless %s with Logo3-ID %sn", pszLnkName, pszLogo3ID );
  172.                     }
  173.                     if ( pszDarwinID )
  174.                     {
  175.                         if ( FAILED(hr = SetLnkBlessing(pishl, DARWIN_ID, pszDarwinID)) )
  176.                             fprintf( stderr, "err - failed to bless %s with Darwin-ID %sn", pszLnkName, pszDarwinID );
  177.                                         }
  178.                         }
  179.                         if ( SUCCEEDED(hr) )
  180.                                 hr = pipfLnk->Save( NULL, FALSE );
  181.                         if ( FAILED(hr) )
  182.                                 fprintf( stderr, "err - failed with error %lxn", hr );
  183.         }
  184.         pipfLnk->Release();
  185.     }
  186.     if (pszCDFURL && SUCCEEDED(hr)) {
  187.         // BUGBUG: pszLogo3ID is passed instead of a friendly name. In
  188.         // the future, we can add another switch to blesslnk to accomodate
  189.         // this. Also, we must subscribe with UI (non-silent mode) because
  190.         // subscribing will not work properly otherwise.
  191.         SubscribeChannel(NULL, pszLogo3ID, pszCDFURL, FALSE);
  192.     }
  193.         
  194.     CoUninitialize();
  195.             
  196.     return iReturn;
  197. }