assoc.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 21k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * assoc.c - Type association routines.
  3.  */
  4. /* Headers
  5.  **********/
  6. #include "project.h"
  7. #pragma hdrstop
  8. #include <mluisupp.h>
  9. #define _INTSHCUT_               /* for intshcut.h */
  10. #include <intshcut.h>
  11. #ifdef WINNT_ENV
  12. #include <intshctp.h>  /* ALL_???_FLAGS */
  13. #endif
  14. #include "assoc.h"
  15. #include "extricon.h"
  16. #include "openas.h"
  17. #pragma warning(disable:4001) /* "single line comment" warning */
  18. #include "filetype.h"
  19. #include "resource.h"
  20. #pragma warning(default:4001) /* "single line comment" warning */
  21. #include "shlstock.h"
  22. #include "shlvalid.h"
  23. /* Global Constants
  24.  *******************/
  25. #pragma data_seg(DATA_SEG_READ_ONLY)
  26. PUBLIC_DATA const HKEY g_hkeyURLProtocols          = HKEY_CLASSES_ROOT;
  27. PUBLIC_DATA const HKEY g_hkeyMIMESettings          = HKEY_CLASSES_ROOT;
  28. PUBLIC_DATA CCHAR g_cszURLProtocol[]               = "URL Protocol";
  29. PUBLIC_DATA CCHAR g_cszContentType[]               = "Content Type";
  30. PUBLIC_DATA CCHAR g_cszExtension[]                 = "Extension";
  31. #pragma data_seg()
  32. /* Module Constants
  33.  *******************/
  34. #pragma data_seg(DATA_SEG_READ_ONLY)
  35. PRIVATE_DATA CCHAR s_cszShellOpenCmdSubKeyFmt[]    = "%s\shell\open\command";
  36. PRIVATE_DATA CCHAR s_cszAppOpenCmdFmt[]            = "%s %%1";
  37. PRIVATE_DATA CCHAR s_cszDefaultIconSubKeyFmt[]     = "%s\DefaultIcon";
  38. PRIVATE_DATA CCHAR s_cszDefaultIcon[]              = "url.dll,0";
  39. #pragma data_seg()
  40. /***************************** Private Functions *****************************/
  41. /*
  42. ** RegisterAppAsURLProtocolHandler()
  43. **
  44. ** Under HKEY_CLASSES_ROOTurl-protocolshellopencommand, add default value =
  45. ** "c:foobar.exe %1".
  46. **
  47. ** Arguments:
  48. **
  49. ** Returns:
  50. **
  51. ** Side Effects:  none
  52. */
  53. PRIVATE_CODE BOOL RegisterAppAsURLProtocolHandler(PCSTR pcszProtocol,
  54.                                                   PCSTR pcszApp)
  55. {
  56.    BOOL bResult = FALSE;
  57.    DWORD dwcbShellOpenCmdSubKeyLen;
  58.    PSTR pszShellOpenCmdSubKey;
  59.    ASSERT(IS_VALID_STRING_PTR(pcszProtocol, CSTR));
  60.    ASSERT(IS_VALID_STRING_PTR(pcszApp, CSTR));
  61.    /* (+ 1) for null terminator. */
  62.    dwcbShellOpenCmdSubKeyLen = sizeof(s_cszShellOpenCmdSubKeyFmt) + 1
  63.                                + lstrlen(pcszProtocol);
  64.    if (AllocateMemory(dwcbShellOpenCmdSubKeyLen, &pszShellOpenCmdSubKey))
  65.    {
  66.       DWORD dwcbAppOpenCmdLen;
  67.       PSTR pszAppOpenCmd;
  68.       /* BUGBUG: We should quote pcszApp here only if it contains spaces. */
  69.       /* (+ 1) for null terminator. */
  70.       dwcbAppOpenCmdLen = sizeof(s_cszAppOpenCmdFmt) + 1 + lstrlen(pcszApp);
  71.       if (AllocateMemory(dwcbAppOpenCmdLen, &pszAppOpenCmd))
  72.       {
  73.          EVAL((DWORD)wsprintf(pszShellOpenCmdSubKey, s_cszShellOpenCmdSubKeyFmt,
  74.                               pcszProtocol) < dwcbShellOpenCmdSubKeyLen);
  75.          EVAL((DWORD)wsprintf(pszAppOpenCmd, s_cszAppOpenCmdFmt, pcszApp)
  76.               < dwcbAppOpenCmdLen);
  77.          /* (+ 1) for null terminator. */
  78.          bResult = (SetRegKeyValue(g_hkeyURLProtocols, pszShellOpenCmdSubKey,
  79.                                    NULL, REG_SZ, (PCBYTE)pszAppOpenCmd,
  80.                                    lstrlen(pszAppOpenCmd) + 1)
  81.                     == ERROR_SUCCESS);
  82.          FreeMemory(pszShellOpenCmdSubKey);
  83.          pszShellOpenCmdSubKey = NULL;
  84.       }
  85.       FreeMemory(pszAppOpenCmd);
  86.       pszAppOpenCmd = NULL;
  87.    }
  88.    return(bResult);
  89. }
  90. /*
  91. ** RegisterURLProtocolDescription()
  92. **
  93. ** Under g_hkeyURLSettingsurl-protocol, add default value =
  94. ** URL:Url-protocol Protocol.
  95. **
  96. ** Arguments:
  97. **
  98. ** Returns:
  99. **
  100. ** Side Effects:  none
  101. */
  102. PRIVATE_CODE BOOL RegisterURLProtocolDescription(PCSTR pcszProtocol)
  103. {
  104.    BOOL bResult = FALSE;
  105.    PSTR pszProtocolCopy;
  106.    ASSERT(IS_VALID_STRING_PTR(pcszProtocol, CSTR));
  107.    if (StringCopy(pcszProtocol, &pszProtocolCopy))
  108.    {
  109.       char szDescriptionFmt[MAX_PATH_LEN];
  110.       /*
  111.        * Convert first character of protocol to upper case for description
  112.        * string.
  113.        */
  114.       *pszProtocolCopy = (CHAR)PtrToUlong(CharUpper((LPSTR)(DWORD)*pszProtocolCopy));
  115.       if (MLLoadStringA(IDS_URL_DESC_FORMAT,
  116.                      szDescriptionFmt, sizeof(szDescriptionFmt)))
  117.       {
  118.          char szDescription[MAX_PATH_LEN];
  119.          if ((UINT)lstrlen(szDescriptionFmt) + (UINT)lstrlen(pszProtocolCopy)
  120.              < sizeof(szDescription))
  121.          {
  122.             EVAL(wsprintf(szDescription, szDescriptionFmt, pszProtocolCopy)
  123.                  < sizeof(szDescription));
  124.             /* (+ 1) for null terminator. */
  125.             bResult = (SetRegKeyValue(g_hkeyURLProtocols, pcszProtocol,
  126.                                       NULL, REG_SZ, (PCBYTE)szDescription,
  127.                                       lstrlen(szDescription) + 1)
  128.                        == ERROR_SUCCESS);
  129.          }
  130.       }
  131.       FreeMemory(pszProtocolCopy);
  132.       pszProtocolCopy = NULL;
  133.    }
  134.    return(bResult);
  135. }
  136. /*
  137. ** RegisterURLProtocolFlags()
  138. **
  139. ** Under g_hkeyURLSettingsurl-protocol, add EditFlags = FTA_Show.
  140. **
  141. ** Arguments:
  142. **
  143. ** Returns:
  144. **
  145. ** Side Effects:  none
  146. */
  147. PRIVATE_CODE BOOL RegisterURLProtocolFlags(PCSTR pcszProtocol)
  148. {
  149.    DWORD dwEditFlags = FTA_Show;
  150.    ASSERT(IS_VALID_STRING_PTR(pcszProtocol, CSTR));
  151.    /* BUGBUG: What about preserving any existing EditFlags here? */
  152.    /* (+ 1) for null terminator. */
  153.    return(SetRegKeyValue(g_hkeyURLProtocols, pcszProtocol, g_cszEditFlags,
  154.                          REG_BINARY, (PCBYTE)&dwEditFlags, sizeof(dwEditFlags))
  155.           == ERROR_SUCCESS);
  156. }
  157. /*
  158. ** RegisterURLProtocol()
  159. **
  160. ** Under g_hkeyURLSettingsurl-protocol, add URL Protocol = "".
  161. **
  162. ** Arguments:
  163. **
  164. ** Returns:
  165. **
  166. ** Side Effects:  none
  167. */
  168. PRIVATE_CODE BOOL RegisterURLProtocol(PCSTR pcszProtocol)
  169. {
  170.    ASSERT(IS_VALID_STRING_PTR(pcszProtocol, CSTR));
  171.    /* (+ 1) for null terminator. */
  172.    return(SetRegKeyValue(g_hkeyURLProtocols, pcszProtocol, g_cszURLProtocol,
  173.                          REG_SZ, (PCBYTE)EMPTY_STRING,
  174.                          lstrlen(EMPTY_STRING) + 1) == ERROR_SUCCESS);
  175. }
  176. /*
  177. ** RegisterURLProtocolDefaultIcon()
  178. **
  179. ** Under g_hkeyURLSettingsurl-protocolDefaultIcon, add default value =
  180. ** app.exe,0.
  181. **
  182. ** Arguments:
  183. **
  184. ** Returns:
  185. **
  186. ** Side Effects:  none
  187. */
  188. PRIVATE_CODE BOOL RegisterURLProtocolDefaultIcon(PCSTR pcszProtocol)
  189. {
  190.    BOOL bResult = FALSE;
  191.    DWORD dwcbDefaultIconSubKeyLen;
  192.    PSTR pszDefaultIconSubKey;
  193.    ASSERT(IS_VALID_STRING_PTR(pcszProtocol, CSTR));
  194.    /* (+ 1) for null terminator. */
  195.    dwcbDefaultIconSubKeyLen = sizeof(s_cszDefaultIconSubKeyFmt) + 1
  196.                               + lstrlen(pcszProtocol);
  197.    if (AllocateMemory(dwcbDefaultIconSubKeyLen, &pszDefaultIconSubKey))
  198.    {
  199.       EVAL((DWORD)wsprintf(pszDefaultIconSubKey, s_cszDefaultIconSubKeyFmt,
  200.                            pcszProtocol) < dwcbDefaultIconSubKeyLen);
  201.       bResult = (SetRegKeyValue(g_hkeyURLProtocols, pszDefaultIconSubKey,
  202.                                 NULL, REG_SZ, (PCBYTE)s_cszDefaultIcon,
  203.                                 sizeof(s_cszDefaultIcon))
  204.                  == ERROR_SUCCESS);
  205.       FreeMemory(pszDefaultIconSubKey);
  206.       pszDefaultIconSubKey = NULL;
  207.    }
  208.    return(bResult);
  209. }
  210. PRIVATE_CODE BOOL AllowedToRegisterMIMEType(PCSTR pcszMIMEContentType)
  211. {
  212.    BOOL bResult;
  213. #pragma data_seg(DATA_SEG_READ_ONLY)
  214.    bResult = (lstrcmpi(pcszMIMEContentType, "application/octet-stream") != 0 &&
  215.               lstrcmpi(pcszMIMEContentType, "application/octet-string") != 0);
  216. #pragma data_seg()
  217.    if (bResult)
  218.       TRACE_OUT(("AllowedToRegisterMIMEType(): MIME type %s may be registered.",
  219.                  pcszMIMEContentType));
  220.    else
  221.       WARNING_OUT(("AllowedToRegisterMIMEType(): MIME type %s may not be registered.",
  222.                    pcszMIMEContentType));
  223.    return(bResult);
  224. }
  225. /****************************** Public Functions *****************************/
  226. /*
  227. ** RegisterMIMETypeForExtension()
  228. **
  229. ** Under HKEY_CLASSES_ROOT.ext, add Content Type = mime/type.
  230. **
  231. ** Arguments:
  232. **
  233. ** Returns:
  234. **
  235. ** Side Effects:  none
  236. */
  237. PUBLIC_CODE BOOL RegisterMIMETypeForExtension(PCSTR pcszExtension,
  238.                                                PCSTR pcszMIMEContentType)
  239. {
  240.    ASSERT(IS_VALID_STRING_PTR(pcszExtension, CSTR));
  241.    ASSERT(IS_VALID_STRING_PTR(pcszMIMEContentType, CSTR));
  242.    ASSERT(IsValidExtension(pcszExtension));
  243.    /* (+ 1) for null terminator. */
  244.    return(SetRegKeyValue(HKEY_CLASSES_ROOT, pcszExtension, g_cszContentType, REG_SZ,
  245.                          (PCBYTE)pcszMIMEContentType,
  246.                          lstrlen(pcszMIMEContentType) + 1) == ERROR_SUCCESS);
  247. }
  248. /*
  249. ** UnregisterMIMETypeForExtension()
  250. **
  251. ** Deletes Content Type under HKEY_CLASSES_ROOT.ext.
  252. **
  253. ** Arguments:
  254. **
  255. ** Returns:
  256. **
  257. ** Side Effects:  none
  258. */
  259. PUBLIC_CODE BOOL UnregisterMIMETypeForExtension(PCSTR pcszExtension)
  260. {
  261.    ASSERT(IS_VALID_STRING_PTR(pcszExtension, CSTR));
  262.    ASSERT(IsValidExtension(pcszExtension));
  263.    return(NO_ERROR == SHDeleteValue(HKEY_CLASSES_ROOT, pcszExtension, g_cszContentType));
  264. }
  265. /*
  266. ** RegisterExtensionForMIMEType()
  267. **
  268. ** Under g_hkeyMIMESettingsMIMEDatabaseContent Typemime/type, add
  269. ** Content Type = mime/type and Extension = .ext.
  270. **
  271. ** Arguments:
  272. **
  273. ** Returns:
  274. **
  275. ** Side Effects:  none
  276. */
  277. PUBLIC_CODE BOOL RegisterExtensionForMIMEType(PCSTR pcszExtension,
  278.                                                PCSTR pcszMIMEContentType)
  279. {
  280.    BOOL bResult;
  281.    char szMIMEContentTypeSubKey[MAX_PATH_LEN];
  282.    ASSERT(IS_VALID_STRING_PTR(pcszExtension, CSTR));
  283.    ASSERT(IS_VALID_STRING_PTR(pcszMIMEContentType, CSTR));
  284.    ASSERT(IsValidExtension(pcszExtension));
  285.    bResult = GetMIMETypeSubKey(pcszMIMEContentType, szMIMEContentTypeSubKey,
  286.                                sizeof(szMIMEContentTypeSubKey));
  287.    if (bResult)
  288.       /* (+ 1) for null terminator. */
  289.       bResult = (SetRegKeyValue(g_hkeyMIMESettings, szMIMEContentTypeSubKey,
  290.                                 g_cszExtension, REG_SZ, (PCBYTE)pcszExtension,
  291.                                 lstrlen(pcszExtension) + 1) == ERROR_SUCCESS);
  292.    if (bResult)
  293.       TRACE_OUT(("RegisterExtensionForMIMEType(): Registered extension %s as default extension for MIME type %s.",
  294.                  pcszExtension,
  295.                  pcszMIMEContentType));
  296.    else
  297.       WARNING_OUT(("RegisterExtensionForMIMEType(): Failed to register extension %s as default extension for MIME type %s.",
  298.                    pcszExtension,
  299.                    pcszMIMEContentType));
  300.    return(bResult);
  301. }
  302. /*
  303. ** UnregisterExtensionForMIMEType()
  304. **
  305. ** Deletes Extension under
  306. ** g_hkeyMIMESettingsMIMEDatabaseContent Typemime/type.  If no other values
  307. ** or sub keys are left, deletes
  308. ** g_hkeyMIMESettingsMIMEDatabaseContent Typemime/type.
  309. **
  310. ** Arguments:
  311. **
  312. ** Returns:
  313. **
  314. ** Side Effects:  May also delete MIME key.
  315. */
  316. PUBLIC_CODE BOOL UnregisterExtensionForMIMEType(PCSTR pcszMIMEContentType)
  317. {
  318.    BOOL bResult;
  319.    char szMIMEContentTypeSubKey[MAX_PATH_LEN];
  320.    ASSERT(IS_VALID_STRING_PTR(pcszMIMEContentType, CSTR));
  321.    bResult = (GetMIMETypeSubKey(pcszMIMEContentType, szMIMEContentTypeSubKey,
  322.                                 sizeof(szMIMEContentTypeSubKey)) &&
  323.               SHDeleteValue(g_hkeyMIMESettings, szMIMEContentTypeSubKey,
  324.                                 g_cszExtension) == ERROR_SUCCESS &&
  325.               SHDeleteOrphanKey(g_hkeyMIMESettings, szMIMEContentTypeSubKey) == ERROR_SUCCESS);
  326.    if (bResult)
  327.       TRACE_OUT(("UnregisterExtensionForMIMEType(): Unregistered default extension for MIME type %s.",
  328.                  pcszMIMEContentType));
  329.    else
  330.       WARNING_OUT(("UnregisterExtensionForMIMEType(): Failed to unregister default extension for MIME type %s.",
  331.                    pcszMIMEContentType));
  332.    return(bResult);
  333. }
  334. PUBLIC_CODE BOOL RegisterMIMEAssociation(PCSTR pcszFile,
  335.                                          PCSTR pcszMIMEContentType)
  336. {
  337.    BOOL bResult;
  338.    PCSTR pcszExtension;
  339.    ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  340.    ASSERT(IS_VALID_STRING_PTR(pcszMIMEContentType, CSTR));
  341.    pcszExtension = ExtractExtension(pcszFile);
  342.     /*
  343.      * Don't allow association of flag unknown MIME types
  344.      * application/octet-stream and application/octet-string.
  345.      */
  346.    if (EVAL(*pcszExtension) &&
  347.        AllowedToRegisterMIMEType(pcszMIMEContentType))
  348.       bResult = (RegisterMIMETypeForExtension(pcszExtension, pcszMIMEContentType) &&
  349.                  RegisterExtensionForMIMEType(pcszExtension, pcszMIMEContentType));
  350.    else
  351.       bResult = FALSE;
  352.    return(bResult);
  353. }
  354. PUBLIC_CODE BOOL RegisterURLAssociation(PCSTR pcszProtocol, PCSTR pcszApp)
  355. {
  356.    ASSERT(IS_VALID_STRING_PTR(pcszProtocol, CSTR));
  357.    ASSERT(IS_VALID_STRING_PTR(pcszApp, CSTR));
  358.    return(RegisterAppAsURLProtocolHandler(pcszProtocol, pcszApp) &&
  359.           RegisterURLProtocolDescription(pcszProtocol) &&
  360.           RegisterURLProtocol(pcszProtocol) &&
  361.           RegisterURLProtocolFlags(pcszProtocol) &&
  362.           RegisterURLProtocolDefaultIcon(pcszProtocol));
  363. }
  364. PUBLIC_CODE HRESULT MyMIMEAssociationDialog(HWND hwndParent, DWORD dwInFlags,
  365.                                             PCSTR pcszFile,
  366.                                             PCSTR pcszMIMEContentType,
  367.                                             PSTR pszAppBuf, UINT ucAppBufLen)
  368. {
  369.    HRESULT hr;
  370.    OPENASINFO oainfo;
  371.    ASSERT(IS_VALID_HANDLE(hwndParent, WND));
  372.    ASSERT(FLAGS_ARE_VALID(dwInFlags, ALL_MIMEASSOCDLG_FLAGS));
  373.    ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  374.    ASSERT(IS_VALID_STRING_PTR(pcszMIMEContentType, CSTR));
  375.    ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszAppBuf, STR, ucAppBufLen));
  376.    /* Use default file name if not supplied by caller. */
  377.    if (ucAppBufLen > 0)
  378.       *pszAppBuf = '';
  379.    oainfo.pcszFile = pcszFile;
  380.    oainfo.pcszClass = pcszMIMEContentType;
  381.    oainfo.dwInFlags = 0;
  382.    if (IS_FLAG_SET(dwInFlags, MIMEASSOCDLG_FL_REGISTER_ASSOC))
  383.       SET_FLAG(oainfo.dwInFlags, (OPENASINFO_FL_ALLOW_REGISTRATION |
  384.                                   OPENASINFO_FL_REGISTER_EXT));
  385.    hr = MyOpenAsDialog(hwndParent, &oainfo);
  386.    if (hr == S_OK &&
  387.        IS_FLAG_SET(dwInFlags, MIMEASSOCDLG_FL_REGISTER_ASSOC))
  388.       hr = RegisterMIMEAssociation(pcszFile, pcszMIMEContentType) ? S_OK
  389.                                                                   : E_OUTOFMEMORY;
  390.    if (SUCCEEDED(hr))
  391.       lstrcpyn(pszAppBuf, oainfo.szApp, ucAppBufLen);
  392.    ASSERT(! ucAppBufLen ||
  393.           (IS_VALID_STRING_PTR(pszAppBuf, STR) &&
  394.            EVAL((UINT)lstrlen(pszAppBuf) < ucAppBufLen)));
  395.    ASSERT(SUCCEEDED(hr) ||
  396.           (! ucAppBufLen ||
  397.            EVAL(! *pszAppBuf)));
  398.    return(hr);
  399. }
  400. PUBLIC_CODE HRESULT MyURLAssociationDialog(HWND hwndParent, DWORD dwInFlags,
  401.                                            PCSTR pcszFile, PCSTR pcszURL,
  402.                                            PSTR pszAppBuf, UINT ucAppBufLen)
  403. {
  404.    HRESULT hr;
  405.    PSTR pszProtocol;
  406.    ASSERT(IS_VALID_HANDLE(hwndParent, WND));
  407.    ASSERT(FLAGS_ARE_VALID(dwInFlags, ALL_URLASSOCDLG_FLAGS));
  408.    ASSERT(IS_FLAG_SET(dwInFlags, URLASSOCDLG_FL_USE_DEFAULT_NAME) ||
  409.           IS_VALID_STRING_PTR(pcszFile, CSTR));
  410.    ASSERT(IS_VALID_STRING_PTR(pcszURL, CSTR));
  411.    ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszAppBuf, STR, ucAppBufLen));
  412.    /* Use URL protocol as class name. */
  413.    if (ucAppBufLen > 0)
  414.       *pszAppBuf = '';
  415.    hr = CopyURLProtocol(pcszURL, &pszProtocol);
  416.    if (hr == S_OK)
  417.    {
  418.       char szInternetShortcut[MAX_PATH_LEN];
  419.       OPENASINFO oainfo;
  420.       /* Use default file name if not supplied by caller. */
  421.       if (IS_FLAG_SET(dwInFlags, URLASSOCDLG_FL_USE_DEFAULT_NAME) &&
  422.           EVAL(MLLoadStringA(IDS_INTERNET_SHORTCUT,
  423.                           szInternetShortcut, sizeof(szInternetShortcut))))
  424.          pcszFile = szInternetShortcut;
  425.       oainfo.pcszFile = pcszFile;
  426.       oainfo.pcszClass = pszProtocol;
  427.       oainfo.dwInFlags = 0;
  428.       if (IS_FLAG_SET(dwInFlags, URLASSOCDLG_FL_REGISTER_ASSOC))
  429.          SET_FLAG(oainfo.dwInFlags, OPENASINFO_FL_ALLOW_REGISTRATION);
  430.       hr = MyOpenAsDialog(hwndParent, &oainfo);
  431.       if (hr == S_OK &&
  432.           IS_FLAG_SET(dwInFlags, URLASSOCDLG_FL_REGISTER_ASSOC))
  433.          hr = RegisterURLAssociation(pszProtocol, oainfo.szApp) ? S_OK
  434.                                                                 : E_OUTOFMEMORY;
  435.       if (SUCCEEDED(hr))
  436.          lstrcpyn(pszAppBuf, oainfo.szApp, ucAppBufLen);
  437.       FreeMemory(pszProtocol);
  438.       pszProtocol = NULL;
  439.    }
  440.    ASSERT(! ucAppBufLen ||
  441.           (IS_VALID_STRING_PTR(pszAppBuf, STR) &&
  442.            EVAL((UINT)lstrlen(pszAppBuf) < ucAppBufLen)));
  443.    ASSERT(SUCCEEDED(hr) ||
  444.           (! ucAppBufLen ||
  445.            EVAL(! *pszAppBuf)));
  446.    return(hr);
  447. }
  448. #ifdef DEBUG
  449. PUBLIC_CODE BOOL IsValidPCOPENASINFO(PCOPENASINFO pcoainfo)
  450. {
  451.    return(IS_VALID_READ_PTR(pcoainfo, COPENASINFO) &&
  452.           IS_VALID_STRING_PTR(pcoainfo->pcszFile, CSTR) &&
  453.           (! pcoainfo->pcszClass ||
  454.            IS_VALID_STRING_PTR(pcoainfo->pcszClass, CSTR)) &&
  455.           FLAGS_ARE_VALID(pcoainfo->dwInFlags, ALL_OPENASINFO_FLAGS) &&
  456.           (! *pcoainfo->szApp ||
  457.            IS_VALID_STRING_PTR(pcoainfo->szApp, STR)));
  458. }
  459. #endif   /* DEBUG */
  460. /***************************** Exported Functions ****************************/
  461. INTSHCUTAPI HRESULT WINAPI MIMEAssociationDialogA(HWND hwndParent,
  462.                                                   DWORD dwInFlags,
  463.                                                   PCSTR pcszFile,
  464.                                                   PCSTR pcszMIMEContentType,
  465.                                                   PSTR pszAppBuf,
  466.                                                   UINT ucAppBufLen)
  467. {
  468.    HRESULT hr;
  469.    DebugEntry(MIMEAssociationDialogA);
  470. #ifdef EXPV
  471.    /* Verify parameters. */
  472.    if (IS_VALID_HANDLE(hwndParent, WND) &&
  473.        IS_VALID_STRING_PTR(pcszFile, CSTR) &&
  474.        IS_VALID_STRING_PTR(pcszMIMEContentType, CSTR) &&
  475.        IS_VALID_WRITE_BUFFER_PTR(pszAppBuf, STR, ucAppBufLen))
  476.    {
  477.       if (FLAGS_ARE_VALID(dwInFlags, ALL_MIMEASSOCDLG_FLAGS))
  478. #endif
  479.       {
  480.          hr = MyMIMEAssociationDialog(hwndParent, dwInFlags, pcszFile,
  481.                                       pcszMIMEContentType, pszAppBuf,
  482.                                       ucAppBufLen);
  483.       }
  484. #ifdef EXPV
  485.       else
  486.          hr = E_FLAGS;
  487.    }
  488.    else
  489.       hr = E_POINTER;
  490. #endif
  491.    DebugExitHRESULT(MIMEAssociationDialogA, hr);
  492.    return(hr);
  493. }
  494. #pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
  495. INTSHCUTAPI HRESULT WINAPI MIMEAssociationDialogW(HWND hwndParent,
  496.                                                   DWORD dwInFlags,
  497.                                                   PCWSTR pcszFile,
  498.                                                   PCWSTR pcszMIMEContentType,
  499.                                                   PWSTR pszAppBuf,
  500.                                                   UINT ucAppBufLen)
  501. {
  502.    HRESULT hr;
  503.    DebugEntry(MIMEAssociationDialogW);
  504.    SetLastError(ERROR_NOT_SUPPORTED);
  505.    hr = E_NOTIMPL;
  506.    DebugExitHRESULT(MIMEAssociationDialogW, hr);
  507.    return(hr);
  508. }
  509. #pragma warning(default:4100) /* "unreferenced formal parameter" warning */
  510. INTSHCUTAPI HRESULT WINAPI URLAssociationDialogA(HWND hwndParent,
  511.                                                  DWORD dwInFlags,
  512.                                                  PCSTR pcszFile, PCSTR pcszURL,
  513.                                                  PSTR pszAppBuf,
  514.                                                  UINT ucAppBufLen)
  515. {
  516.    HRESULT hr;
  517.    DebugEntry(URLAssociationDialogA);
  518. #ifdef EXPV
  519.    /* Verify parameters. */
  520.    if (IS_VALID_HANDLE(hwndParent, WND) &&
  521.        (IS_FLAG_SET(dwInFlags, URLASSOCDLG_FL_USE_DEFAULT_NAME) ||
  522.         IS_VALID_STRING_PTR(pcszFile, CSTR)) &&
  523.        IS_VALID_STRING_PTR(pcszURL, CSTR) &&
  524.        IS_VALID_WRITE_BUFFER_PTR(pszAppBuf, STR, ucAppBufLen))
  525.    {
  526.       if (FLAGS_ARE_VALID(dwInFlags, ALL_URLASSOCDLG_FLAGS))
  527. #endif
  528.       {
  529.          hr = MyURLAssociationDialog(hwndParent, dwInFlags, pcszFile, pcszURL,
  530.                                      pszAppBuf, ucAppBufLen);
  531.       }
  532. #ifdef EXPV
  533.       else
  534.          hr = E_FLAGS;
  535.    }
  536.    else
  537.       hr = E_POINTER;
  538. #endif
  539.    DebugExitHRESULT(URLAssociationDialogA, hr);
  540.    return(hr);
  541. }
  542. #pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
  543. INTSHCUTAPI HRESULT WINAPI URLAssociationDialogW(HWND hwndParent,
  544.                                                  DWORD dwInFlags,
  545.                                                  PCWSTR pcszFile,
  546.                                                  PCWSTR pcszURL,
  547.                                                  PWSTR pszAppBuf,
  548.                                                  UINT ucAppBufLen)
  549. {
  550.    HRESULT hr;
  551.    DebugEntry(URLAssociationDialogW);
  552.    SetLastError(ERROR_NOT_SUPPORTED);
  553.    hr = E_NOTIMPL;
  554.    DebugExitHRESULT(URLAssociationDialogW, hr);
  555.    return(hr);
  556. }
  557. #pragma warning(default:4100) /* "unreferenced formal parameter" warning */