shassoc.cpp
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 73k
Category:

Windows Develop

Development Platform:

Visual C++

  1. /****************************************************************************
  2.  *
  3.  *  Microsoft Confidential
  4.  *  Copyright (c) Microsoft Corporation 1994
  5.  *  All rights reserved
  6.  *
  7.  * This module handles the File Association UI
  8.  *
  9.  ***************************************************************************/
  10. #include "inetcplp.h"
  11. #include "mluisupp.h"
  12. #include <unistd.h>
  13. // For definition of FTA_OpenIsSafe
  14. // the file class's open verb may be safely invoked for downloaded files
  15. #include "../inc/filetype.h"
  16. // Macros required for default button processing
  17. #define REMOVE_DEF_BORDER(hDlg, cntrl )  
  18.     SendMessage( hDlg,  DM_SETDEFID, -1, 0 ); 
  19.     SendDlgItemMessage( hDlg, cntrl, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );  
  20. #define SET_DEF_BORDER(hDlg, cntrl )  
  21.     SendMessage( hDlg, DM_SETDEFID, cntrl, 0 );   
  22.     SendDlgItemMessage( hDlg, cntrl, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );  
  23. // Editing modes
  24. #define NORMAL   0x00
  25. #define ADDING   0x01
  26. #define UPDATING 0x02
  27. // Association status
  28. #define NEW      0x01
  29. #define UPD      0x02
  30. #define UNM      0x03
  31. #define LocalRealloc(a, b) LocalReAlloc(a, b, LMEM_MOVEABLE)
  32. static TCHAR g_szDefaultIcon[]  = TEXT("shell32.dll,3");
  33. static TCHAR g_szIEUnix[]       = TEXT("IEUNIX");
  34. static TCHAR g_szIEUnixEntry[]   = TEXT("IEUNIX Specific entry");
  35. static TCHAR g_szEditFlags[]    = TEXT("EditFlags");
  36. static TCHAR g_szDocClass[]     = TEXT("DocClass");
  37. static TCHAR g_szMimeKey[]      = TEXT("MIME\Database\Content Type");
  38. static TCHAR g_szCmndSubKey[]   = TEXT("Shell\Open\Command");
  39. static TCHAR g_szPolicySubKey[] = REGSTR_PATH_INETCPL_RESTRICTIONS;
  40. static TCHAR g_szPolicyName[]   = TEXT("Mappings");
  41. int SwitchToAddMode( HWND hDlg );
  42. int SwitchToNrmlMode( HWND hDlg );
  43. BOOL CALLBACK EnterAssocDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  44. BOOL IsAssocEnabled()
  45. {
  46.     HKEY  hKey = NULL;
  47.     LONG lResult = RegOpenKey(HKEY_CURRENT_USER, g_szPolicySubKey, &hKey);
  48.     if( lResult == ERROR_SUCCESS )
  49.     {
  50. // Get then size first
  51. DWORD dwPolicy, dwType, dwSize = sizeof(DWORD);
  52. if (RegQueryValueEx( hKey, g_szPolicyName, NULL, &dwType, (LPBYTE)&dwPolicy, &dwSize ) == ERROR_SUCCESS )
  53. {
  54.     if( dwPolicy )
  55.     {
  56.         RegCloseKey( hKey );
  57.         return FALSE;
  58.     }
  59. }
  60. RegCloseKey( hKey );
  61.     }
  62.     return TRUE;
  63. }
  64. /*
  65. ** AddStringToComboBox()
  66. **
  67. ** Adds a string to a combo box.  Does not check to see if the string has
  68. ** already been added.
  69. **
  70. ** Arguments:
  71. **
  72. ** Returns:
  73. **
  74. ** Side Effects:  none
  75. */
  76. BOOL AddStringToComboBox(HWND hwndComboBox, LPCTSTR pcsz)
  77. {
  78.    BOOL bResult;
  79.    LONG lAddStringResult;
  80.    lAddStringResult = SendMessage(hwndComboBox, CB_ADDSTRING, 0, (LPARAM)pcsz);
  81.    bResult = (lAddStringResult != CB_ERR &&
  82.               lAddStringResult != CB_ERRSPACE);
  83.    return(bResult);
  84. }
  85. /*
  86. ** SafeAddStringToComboBox()
  87. **
  88. ** Adds a string to a combo box.  Checks to see if the string has already been
  89. ** added.
  90. **
  91. ** Arguments:
  92. **
  93. ** Returns:
  94. **
  95. ** Side Effects:  none
  96. */
  97. BOOL SafeAddStringToComboBox(HWND hwndComboBox, LPCTSTR pcsz)
  98. {
  99.    BOOL bResult;
  100.    if (SendMessage(hwndComboBox, CB_FINDSTRINGEXACT, 0, (LPARAM)pcsz) == CB_ERR)
  101.       bResult = AddStringToComboBox(hwndComboBox, pcsz);
  102.    else
  103.    {
  104.       bResult = TRUE;
  105.    }
  106.    return(bResult);
  107. }
  108. typedef struct ASSOCIATION
  109. {
  110.     HWND hDlg;
  111.     int  mode;
  112.     BOOL fInternalChange;
  113.     BOOL fChanged;
  114. } ASSOCINFO, * LPASSOCTABINFO;
  115. typedef struct ENTERASSOC
  116. {
  117.     LPASSOCTABINFO pgti;
  118.     TCHAR *pszAssoc;
  119. } ENTERASSOC, * LPENTERASSOC;
  120. #define PGTI_FROM_HDLG( hDlg ) 
  121.     ((LPASSOCTABINFO)GetWindowLong(hDlg, DWL_USER)) 
  122. #define PGTI_FROM_PARENT_HDLG( hDlg ) 
  123.     ((LPASSOCTABINFO)GetWindowLong(GetParent(hDlg), DWL_USER)) 
  124. class CMime
  125. {
  126. public:
  127.     TCHAR * m_mime;
  128.     TCHAR * m_exts;
  129.     CMime( TCHAR * name );
  130.    ~CMime();
  131.     // Operations defined for Asscociation
  132. };
  133. CMime::CMime( TCHAR * name )
  134. {
  135.     m_mime = (TCHAR *) LocalAlloc( LPTR, (lstrlen(name) + 1)*sizeof(TCHAR) );
  136.     StrCpy( m_mime, name );
  137.     m_exts = NULL;
  138. }
  139. CMime::~CMime()
  140. {
  141.     if( m_mime ) LocalFree( m_mime );
  142.     if( m_exts ) LocalFree( m_exts );
  143. }
  144. HDPA mimeList = NULL;
  145. BOOL FreeExtensions( HDPA dpa )
  146. {
  147.     if( dpa == (HDPA)NULL ) return FALSE;
  148.     int count = DPA_GetPtrCount( dpa );
  149.     for(int i=0; i<count; i++ )
  150.     {
  151.         LPTSTR ptr = (LPTSTR)DPA_FastGetPtr( dpa, i );
  152.         if(ptr) LocalFree(ptr);
  153.     }
  154.     DPA_Destroy( dpa );
  155.     return TRUE;
  156. }
  157. class CAssoc
  158. {
  159. public:
  160.     TCHAR * m_type;  // File Type class
  161.     TCHAR * m_desc;  // File TYpe Description
  162.     TCHAR * m_mime;  // File Type Mime
  163.     TCHAR * m_cmnd;  // Shell/open/command
  164.     BOOL    m_safe;  // protected or not
  165.     DWORD   m_edit;  // EditFlags value
  166.     UINT    m_stat;  // Status
  167.     HDPA    m_exts;  // Dynamic array for extensions
  168.     CAssoc( TCHAR * name );
  169.    ~CAssoc();
  170.     
  171.     // Operations defined for Asscociation
  172.     Load();
  173.     Save(); 
  174.     Print();
  175.     Delete();
  176.     // Some helper functions
  177.     HDPA   GetExtsOfAssoc( );
  178.     LPTSTR GetDescOfAssoc( );
  179.     LPTSTR GetMimeOfAssoc( );
  180.     LPTSTR GetCmndOfAssoc( );
  181.     DWORD  GetEditOfAssoc( );
  182. };
  183. // Some Helper Function Prototypes
  184. BOOL     FAR PASCAL InitAssocDialog(HWND hDlg, CAssoc * current = NULL);
  185. void     HandleSelChange( LPASSOCTABINFO pgti , BOOL bChangeAppl = TRUE);
  186. TCHAR *  EatSpaces( TCHAR * str );
  187. TCHAR *  ChopSpaces( TCHAR * str );
  188. TCHAR *  DuplicateString( TCHAR * str );
  189. CAssoc * GetCurrentAssoc( HWND hDlg );
  190. // Member function definitions for CAssoc.
  191. CAssoc::CAssoc( TCHAR * name )
  192. {
  193.     m_type = (TCHAR *) LocalAlloc( LPTR, (lstrlen(name) + 1)*sizeof(TCHAR) );
  194.     StrCpy( m_type, name );
  195.     m_desc = NULL;
  196.     m_mime = NULL;
  197.     m_cmnd = NULL;
  198.     m_stat = NEW ;
  199.     m_safe = TRUE; // Internal Assoc, Dont mess with this
  200.     m_exts = NULL;
  201.     m_edit = 0;
  202. }
  203. CAssoc::~CAssoc()
  204. {
  205.     if( m_type ) LocalFree( m_type );
  206.     if( m_desc ) LocalFree( m_desc );
  207.     if( m_mime ) LocalFree( m_mime );
  208.     if( m_cmnd ) LocalFree( m_cmnd );
  209.     if( m_exts ) FreeExtensions( m_exts );
  210. }
  211. CAssoc::Load()
  212. {
  213.     if(m_type)
  214.     {
  215.        TCHAR * ptr = NULL;
  216.        m_exts = GetExtsOfAssoc();
  217.        m_edit = GetEditOfAssoc();
  218.        if ((ptr = GetDescOfAssoc( )) != NULL)
  219.        { 
  220.           m_desc = (TCHAR *)LocalAlloc( LPTR, (lstrlen(ptr) + 1)*sizeof(TCHAR));
  221.           StrCpy( m_desc, ptr );
  222.           ptr = NULL;
  223.        }
  224.        else 
  225.            // Each type must have a description. (Required)
  226.            return FALSE;
  227.        if ((ptr = GetMimeOfAssoc()) != NULL)
  228.        {
  229.           m_mime = (TCHAR *)LocalAlloc( LPTR, (lstrlen(ptr) + 1)*sizeof(TCHAR));
  230.           StrCpy( m_mime, ptr );
  231.           ptr = NULL;
  232.        }
  233.        if ((ptr = GetCmndOfAssoc()) != NULL)
  234.        {
  235.           m_cmnd = (TCHAR *)LocalAlloc( LPTR, (lstrlen(ptr) + 1)*sizeof(TCHAR));
  236.           StrCpy( m_cmnd, ptr );
  237.           ptr = NULL;
  238.        }
  239.        m_stat = UNM;
  240.        m_safe = FALSE;
  241.     }
  242.     return TRUE;
  243. }
  244. CAssoc::Save()
  245. {
  246.     if( m_safe ) return TRUE;
  247.     if( m_stat != UPD ) return TRUE;
  248.     // Create a Key for DocType in HKEY_CLASSES_ROOT
  249.     // [doctype
  250.     //   (--reg-val-- "Description")
  251.     //   [defaulticon
  252.     //      (reg-val "shell32.dll,3")
  253.     //   ]
  254.     //   [shell
  255.     //     [open
  256.     //       [command
  257.     //         (--reg-val-- "Command" )
  258.     //       ]
  259.     //     ]
  260.     //   ]
  261.     // ]
  262.     HKEY hKey1, hKey2, hKey3, hKey4;
  263.     LONG lResult = RegOpenKeyEx(
  264.             HKEY_CLASSES_ROOT,
  265.             m_type,
  266.             0,
  267.             KEY_QUERY_VALUE|KEY_WRITE,
  268.             &hKey1);
  269.     if (lResult != ERROR_SUCCESS)
  270.     {
  271.         lResult = RegCreateKey(
  272.         HKEY_CLASSES_ROOT,
  273.         m_type,
  274.         &hKey1);
  275.     }
  276.     if (lResult == ERROR_SUCCESS)
  277.     {
  278.         DWORD dwType = REG_SZ;
  279.         DWORD dwLen  = (lstrlen(m_desc)+1)*sizeof(TCHAR);
  280.         RegSetValue( hKey1, NULL, dwType, m_desc, dwLen );
  281.         // Add IEUNIX tag to this entry
  282.         dwLen  = (lstrlen(g_szIEUnixEntry)+1)*sizeof(TCHAR);
  283.         RegSetValueEx( hKey1, g_szIEUnix, 0,
  284.             dwType, (LPBYTE)g_szIEUnixEntry, dwLen );
  285.         
  286.         // Add Edit flags to this entry
  287.         DWORD value = m_edit;
  288.         RegSetValueEx( hKey1, g_szEditFlags, 0,
  289.             REG_DWORD, (LPBYTE)(&value), sizeof(DWORD) ); 
  290.         HKEY hKey2;
  291.         RegDeleteKey( hKey1, TEXT("defaulticon" ) );
  292.        
  293.         lResult = RegCreateKey(
  294.             hKey1,
  295.             TEXT("defaulticon"),
  296.             &hKey2);
  297.         if(lResult == ERROR_SUCCESS)
  298.         {
  299.             DWORD dwType = REG_SZ;
  300.             DWORD dwLen  = (lstrlen(g_szDefaultIcon)+1)*sizeof(TCHAR);
  301.             RegSetValue( hKey2, NULL, dwType, g_szDefaultIcon, dwLen );
  302.             RegCloseKey( hKey2);
  303.         }
  304.         RegDeleteKey( hKey1, g_szCmndSubKey );
  305.         lResult = RegOpenKeyEx(
  306.                 hKey1,
  307.                 TEXT("shell"),
  308.                 0,
  309.                 KEY_QUERY_VALUE| KEY_WRITE,
  310.                 &hKey2);
  311.        
  312.         if(lResult != ERROR_SUCCESS)
  313.         {
  314.             lResult = RegCreateKey(
  315.                 hKey1,
  316.                 TEXT("shell"),
  317.                 &hKey2);      
  318.         }
  319.         if(lResult == ERROR_SUCCESS)
  320.         {
  321.             lResult = RegOpenKeyEx(
  322.                 hKey2,
  323.                 TEXT("open"),
  324.                 0,
  325.                 KEY_QUERY_VALUE| KEY_WRITE,
  326.                 &hKey3);
  327.             if( lResult != ERROR_SUCCESS )
  328.             {
  329.                 lResult = RegCreateKey(
  330.                     hKey2,
  331.                     TEXT("open"),
  332.                     &hKey3);      
  333.             }
  334.             if( lResult == ERROR_SUCCESS )
  335.             {
  336.                 lResult = RegOpenKeyEx(
  337.                     hKey3,
  338.                     TEXT("command"),
  339.                     0,
  340.                     KEY_QUERY_VALUE| KEY_WRITE,
  341.                     &hKey4);
  342.                 if( lResult != ERROR_SUCCESS )
  343.                 {
  344.                     lResult = RegCreateKey(
  345.                         hKey3,
  346.                         TEXT("command"),
  347.                         &hKey4);      
  348.                 }
  349.                 if( lResult == ERROR_SUCCESS )
  350.                 {
  351.                     DWORD dwType = REG_SZ;
  352.                     DWORD dwLen  = (lstrlen(m_cmnd)+1)*sizeof(TCHAR);
  353.                     RegSetValue( hKey4, NULL, dwType, m_cmnd, dwLen );
  354.                     RegCloseKey( hKey4);
  355.                 }
  356.                
  357.                 RegCloseKey(hKey3);
  358.             }
  359.             RegCloseKey(hKey2);
  360.         }   
  361.         RegCloseKey(hKey1);
  362.     }    
  363.   
  364.     // Add mime type to the mimetype data base if it doesn't exist
  365.     LPTSTR mimeKey = (LPTSTR)LocalAlloc( LPTR, (lstrlen(m_mime)+lstrlen(g_szMimeKey) + 3)*sizeof(TCHAR));
  366.     
  367.     if(mimeKey && m_mime)
  368.     {
  369.         StrCpy( mimeKey, g_szMimeKey );
  370.         StrCat( mimeKey, TEXT("\")  );
  371.         StrCat( mimeKey, m_mime      );
  372.         
  373.         lResult = RegOpenKeyEx(
  374.                 HKEY_CLASSES_ROOT,
  375.                 mimeKey,
  376.                 0,
  377.                 KEY_QUERY_VALUE| KEY_WRITE,
  378.                 &hKey1);
  379.     
  380.         if(lResult != ERROR_SUCCESS)
  381.         {
  382.             lResult = RegCreateKey(
  383.                 HKEY_CLASSES_ROOT,
  384.                 mimeKey,
  385.                 &hKey1);
  386.             if(lResult == ERROR_SUCCESS && m_exts)
  387.             {
  388.                 int count    = DPA_GetPtrCount( m_exts );
  389.                 if(count > 0 )
  390.                 {
  391.                     LPTSTR firstExt = (LPTSTR)DPA_FastGetPtr( m_exts, 0 );
  392.                     RegSetValueEx( hKey1, TEXT("extension"), NULL,
  393.                         REG_SZ, (LPBYTE)firstExt, (lstrlen(firstExt)+1)*sizeof(TCHAR) );
  394.                 }
  395.                 RegCloseKey( hKey1 );
  396.             }
  397.         }
  398.         else
  399.         {
  400.             RegCloseKey( hKey1 );
  401.         }
  402.     }
  403.     if(mimeKey) 
  404.          LocalFree(mimeKey);
  405.     // Add extention/document type association
  406.     // [.ext
  407.     //   (--reg-val-- "Application")
  408.     //   (content.type "mimetype"  )
  409.     // ]
  410.     // First remove all the extensions for the current assoc from the
  411.     // registry.
  412.     HDPA prevExts = GetExtsOfAssoc();
  413.     if( prevExts )
  414.     {
  415.         int extCount = DPA_GetPtrCount( prevExts );
  416.         for( int i=0; i< extCount; i++ )
  417.            RegDeleteKey( HKEY_CLASSES_ROOT, (LPTSTR)DPA_FastGetPtr( prevExts, i ) ); 
  418.         FreeExtensions( prevExts );
  419.     }
  420.     if( m_exts )
  421.     {
  422.         int count = DPA_GetPtrCount( m_exts );
  423.         for( int i=0; i<count; i++ )
  424.         { 
  425.             LPTSTR ptr = (LPTSTR)DPA_FastGetPtr( m_exts, i );
  426.             if( ptr && *ptr == TEXT('.') )
  427.             {
  428.                 lResult = RegOpenKeyEx(
  429.                     HKEY_CLASSES_ROOT,
  430.                     ptr,
  431.                     0,
  432.                     KEY_QUERY_VALUE| KEY_WRITE,
  433.                     &hKey1);
  434.                 if( lResult != ERROR_SUCCESS )
  435.                 {
  436.                     lResult = RegCreateKey(
  437.                         HKEY_CLASSES_ROOT,
  438.                         ptr, 
  439.                         &hKey1);      
  440.                 }
  441.                 if( lResult == ERROR_SUCCESS )
  442.                 {
  443.                     DWORD dwType = REG_SZ;
  444.                     DWORD dwLen  = (lstrlen(m_type)+1)*sizeof(TCHAR);
  445.                     RegSetValue( hKey1, NULL, dwType, m_type, dwLen );
  446.                        
  447.                     EatSpaces(m_mime ); 
  448.                     dwLen  = lstrlen(m_mime);
  449.                     if(m_mime && (dwLen=lstrlen(m_mime))>0)
  450.                         RegSetValueEx( hKey1, TEXT("Content Type"), 0,
  451.                             dwType, (LPBYTE)m_mime, (dwLen+1)*sizeof(TCHAR) );
  452.                     // Add IEUNIX tag to this entry
  453.                     dwLen  = (lstrlen(g_szIEUnixEntry)+1)*sizeof(TCHAR);
  454.                     RegSetValueEx( hKey1, g_szIEUnix, 0,
  455.                         dwType, (LPBYTE)g_szIEUnixEntry, dwLen );
  456.                     RegCloseKey( hKey1);
  457.                     hKey1 = NULL;
  458.                 }
  459.             }
  460.         }
  461.     } 
  462.     else
  463.         return FALSE; 
  464.     
  465.     return TRUE;
  466. }
  467. CAssoc::Delete()
  468. {
  469.     HKEY hKey;
  470.     
  471.     // Don't touch the safe keys
  472.     if( m_safe ) return FALSE;
  473.     // Delete Application from HKEY_CLASSES_ROOT
  474.     EatSpaces(m_type);
  475.     if(m_type && *m_type)
  476.     {
  477.         // NT restrictions
  478.         TCHAR * key = (TCHAR *)LocalAlloc(LPTR, (lstrlen(m_type) + 200)*sizeof(TCHAR) ) ;
  479.         if(!key) return FALSE;
  480.         
  481.         StrCpy( key, m_type );        
  482.         StrCat( key, TEXT("\defaulticon") );        
  483.         RegDeleteKey(HKEY_CLASSES_ROOT, key);
  484.         StrCpy( key, m_type );        
  485.         StrCat( key, TEXT("\") );        
  486.         StrCat( key, g_szCmndSubKey );
  487.         RegDeleteKey(HKEY_CLASSES_ROOT, key);
  488.         StrCpy( key, m_type );        
  489.         StrCat( key, TEXT("\shell\open") );        
  490.         RegDeleteKey(HKEY_CLASSES_ROOT, key);
  491.         StrCpy( key, m_type );        
  492.         StrCat( key, TEXT("\shell") );        
  493.         RegDeleteKey(HKEY_CLASSES_ROOT, key);
  494.         RegDeleteKey(HKEY_CLASSES_ROOT, m_type);
  495.         LocalFree( key );
  496.     }
  497.     else
  498.         return FALSE; 
  499.     // Delete Extensions  from HKEY_CLASSES_ROOT
  500.     if( m_exts )
  501.     {
  502.         int count = DPA_GetPtrCount( m_exts );
  503.         for( int i=0; i<count; i++ )
  504.         { 
  505.             LPTSTR ptr = (LPTSTR)DPA_FastGetPtr( m_exts, i );
  506.             if( ptr && *ptr == TEXT('.') )
  507.             {
  508.                 RegDeleteKey(HKEY_CLASSES_ROOT, ptr);
  509.             }
  510.         }
  511.     } 
  512.     else
  513.         return FALSE; 
  514.     return TRUE;
  515. }
  516. CAssoc::Print()
  517. {
  518. #ifndef UNICODE
  519.     if( m_type ) printf( m_type );
  520.     printf(",");
  521.     if( m_desc ) printf( m_desc );
  522.     printf(",");
  523.     if( m_mime ) printf( m_mime );
  524.     printf(",");
  525.     if( m_cmnd ) printf( m_cmnd );
  526.     if( m_exts )
  527.     {
  528.         int count = DPA_GetPtrCount( m_exts );
  529.         for( int i=0; i<count; i++ )
  530.         { 
  531.             LPTSTR ptr = (LPTSTR)DPA_FastGetPtr( m_exts, i );
  532.             if( ptr && *ptr == TEXT('.') )
  533.             {
  534.                 printf("%s;", ptr );
  535.             }
  536.         }
  537.     }
  538.     printf("n");
  539. #endif
  540.     return TRUE;
  541. }
  542. HDPA CAssoc::GetExtsOfAssoc()
  543. {
  544.     TCHAR buffer[MAX_PATH];
  545.     DWORD index  = 0;
  546.     DWORD type   = REG_SZ;
  547.     long  dwLen  = MAX_PATH;
  548.     DWORD dwLen2 = MAX_PATH;
  549.     HDPA  exts = DPA_Create(4);
  550.     
  551.     *buffer = TEXT('');
  552.     if( !m_type ) return NULL;
  553.     TCHAR * key   = (TCHAR *)LocalAlloc( LPTR, (MAX_PATH+1)*sizeof(TCHAR) );
  554.     TCHAR * value = (TCHAR *)LocalAlloc( LPTR, (MAX_PATH+1)*sizeof(TCHAR) );
  555.     if( !key || !value  ) goto EXIT;
  556.     while( RegEnumKey( HKEY_CLASSES_ROOT, index, key, MAX_PATH ) != ERROR_NO_MORE_ITEMS ) 
  557.     {    
  558.         if( *key == TEXT('.') )
  559.         {
  560.             HKEY  hKey = NULL;
  561.             LONG lResult = RegOpenKeyEx(
  562.                 HKEY_CLASSES_ROOT,
  563.                 key,
  564.                 0,
  565.                 KEY_QUERY_VALUE,
  566.                 &hKey);
  567.             if( lResult == ERROR_SUCCESS )
  568.             {
  569.                 // Get then size first
  570.         dwLen = (MAX_PATH+1)*sizeof(TCHAR);
  571. if (RegQueryValue( hKey, NULL, value,  &dwLen )
  572.     == ERROR_SUCCESS )
  573. {
  574.     if( !StrCmpIC( value, m_type ) )
  575.     {
  576. DPA_InsertPtr( exts, 0x7FFF, (LPVOID)DuplicateString(key) );
  577.     }
  578. }
  579.                 RegCloseKey( hKey );
  580.             }
  581.         }
  582.         index++;
  583.     }
  584. EXIT:
  585.     if( key )
  586.         LocalFree( key );
  587.     if( value)
  588.         LocalFree( value );
  589.     return exts;
  590. }
  591. LPTSTR CAssoc::GetDescOfAssoc()
  592. {
  593.     HKEY hKey;
  594.     static TCHAR buffer[MAX_PATH];
  595.     DWORD type  = REG_SZ;
  596.     DWORD dwLen = sizeof(buffer);
  597.     *buffer = TEXT('');
  598.     if( !m_type ) return NULL;
  599.     LONG lResult = RegOpenKeyEx(
  600.         HKEY_CLASSES_ROOT,
  601.         m_type,
  602.         0,
  603.         KEY_QUERY_VALUE | KEY_READ,
  604.         &hKey);
  605.     if (lResult == ERROR_SUCCESS)
  606.     {
  607.         lResult = RegQueryValueEx(
  608.            hKey,
  609.            NULL,
  610.            NULL,
  611.            (LPDWORD) &type,
  612.            (LPBYTE)  buffer,
  613.            (LPDWORD) &dwLen);
  614.         RegCloseKey( hKey );
  615.         if( lResult == ERROR_SUCCESS ) 
  616.         {
  617.             return buffer;
  618.         }
  619.         
  620.     }
  621.     return NULL;
  622. }
  623. DWORD CAssoc::GetEditOfAssoc()
  624. {
  625.     HKEY hKey;
  626.     DWORD buffer = 0;
  627.     DWORD type  = REG_DWORD;
  628.     DWORD dwLen = sizeof(buffer);
  629.     if( !m_type ) return NULL;
  630.     LONG lResult = RegOpenKeyEx(
  631.         HKEY_CLASSES_ROOT,
  632.         m_type,
  633.         0,
  634.         KEY_QUERY_VALUE | KEY_READ,
  635.         &hKey);
  636.     if (lResult == ERROR_SUCCESS)
  637.     {
  638.         lResult = RegQueryValueEx(
  639.            hKey,
  640.            g_szEditFlags, 
  641.            NULL,
  642.            (LPDWORD) &type,
  643.            (LPBYTE)  &buffer,
  644.            (LPDWORD) &dwLen);
  645.         RegCloseKey( hKey );
  646.         if( lResult == ERROR_SUCCESS )
  647.         {
  648.             return buffer;
  649.         }
  650.     }
  651.     return 0;
  652. }
  653. LPTSTR CAssoc::GetMimeOfAssoc()
  654. {
  655.     HKEY hKey;
  656.     static TCHAR buffer[MAX_PATH];
  657.     DWORD type  = REG_SZ;
  658.     DWORD dwLen = sizeof(buffer);
  659.     *buffer = TEXT('');
  660.     if( !m_type || !m_exts ) return NULL;
  661.     int count = DPA_GetPtrCount( m_exts );
  662.     for( int i=0; i< count; i++ )
  663.     {
  664.         LPTSTR str = (LPTSTR)DPA_FastGetPtr( m_exts, i );
  665.         if( !str ) continue;
  666.         LONG lResult = RegOpenKeyEx(
  667.             HKEY_CLASSES_ROOT,
  668.             str,
  669.             0,
  670.             KEY_QUERY_VALUE | KEY_READ,
  671.             &hKey);
  672.         if (lResult == ERROR_SUCCESS)
  673.         {
  674.             lResult = RegQueryValueEx(
  675.                hKey,
  676.                TEXT("Content Type"),
  677.                NULL,
  678.                (LPDWORD) &type,
  679.                (LPBYTE)  buffer,
  680.                (LPDWORD) &dwLen);
  681.             RegCloseKey( hKey );
  682.             if( lResult == ERROR_SUCCESS ) 
  683.             {
  684.                 return buffer;
  685.             }
  686.         }
  687.     }
  688.     return NULL;
  689. }
  690. LPTSTR CAssoc::GetCmndOfAssoc()
  691. {
  692.     HKEY hKey;
  693.     static TCHAR buffer [MAX_PATH];
  694.     TCHAR keyName[MAX_PATH+40];
  695.     DWORD type  = REG_SZ;
  696.     DWORD dwLen = sizeof(buffer);
  697.     *buffer = TEXT('');
  698.     if( !m_type ) return NULL;
  699.     StrCpy( keyName, m_type );
  700.     StrCat( keyName, TEXT("\") );
  701.     StrCat( keyName, g_szCmndSubKey );
  702.     LONG lResult = RegOpenKeyEx(
  703.         HKEY_CLASSES_ROOT,
  704.         keyName,
  705.         0,
  706.         KEY_QUERY_VALUE | KEY_READ,
  707.         &hKey);
  708.     if (lResult == ERROR_SUCCESS)
  709.     {
  710.         lResult = RegQueryValueEx(
  711.            hKey,
  712.            NULL,
  713.            NULL,
  714.            (LPDWORD) &type,
  715.            (LPBYTE)  buffer,
  716.            (LPDWORD) &dwLen);
  717.         RegCloseKey( hKey );
  718.         if( lResult == ERROR_SUCCESS ) 
  719.         {
  720.             return buffer;
  721.         }
  722.     }
  723.     return NULL;
  724. }
  725. HDPA assocList    = (HDPA)NULL;
  726. HDPA assocDelList = (HDPA)NULL;
  727. SetEditLimits(HWND hDlg )
  728. {
  729.     SendMessage(GetDlgItem( hDlg, IDC_DOC_TYPE ), EM_LIMITTEXT, (WPARAM) MAX_PATH-1, 0);
  730.     SendMessage(GetDlgItem( hDlg, IDC_DOC_MIME ), EM_LIMITTEXT, (WPARAM) MAX_PATH-1, 0);
  731.     SendMessage(GetDlgItem( hDlg, IDC_DOC_EXTS ), EM_LIMITTEXT, (WPARAM) MAX_PATH-1, 0);
  732.     SendMessage(GetDlgItem( hDlg, IDC_DOC_DESC ), EM_LIMITTEXT, (WPARAM) MAX_PATH-1, 0);
  733.     SendMessage(GetDlgItem( hDlg, IDC_DOC_CMND ), EM_LIMITTEXT, (WPARAM) MAX_PATH-1, 0);
  734.     return TRUE;
  735. }
  736. TCHAR *DuplicateString( TCHAR *orig )
  737. {
  738.     TCHAR * newStr;
  739.     if( !orig ) return NULL;
  740.     newStr  = (TCHAR *)LocalAlloc( LPTR, (lstrlen(orig) + 1)*sizeof(TCHAR));
  741.     if(newStr) StrCpy( newStr, orig );
  742.     return newStr;
  743. }
  744. TCHAR * EatSpaces( TCHAR * str )
  745. {
  746.     if( !str ) return NULL;
  747.     TCHAR *ptr = str, *tmpStr = DuplicateString( str );
  748.     TCHAR *tmpPtr = tmpStr;
  749.     while( *tmpStr )
  750.     {
  751.         if(*tmpStr == TEXT(' ')  || *tmpStr == TEXT('t') || 
  752.            *tmpStr == TEXT('n') || *tmpStr == TEXT('r') || 
  753.             // Remove special characters.
  754.             (int)(*tmpStr) >= 127)
  755.             tmpStr++; 
  756.         else
  757.             *ptr++ = *tmpStr++;
  758.     }
  759.     *ptr = TEXT('');
  760.     LocalFree( tmpPtr );
  761.     return str;
  762. }
  763. TCHAR * ChopSpaces( TCHAR * str )
  764. {
  765.     if( !str ) return NULL;
  766.     TCHAR *ptr = str;
  767.     while( *ptr && 
  768.          (*ptr == TEXT(' ')  || *ptr == TEXT('t')) ||
  769.          (*ptr == TEXT('n') || *ptr == TEXT('r')) 
  770.          ) ptr++;
  771.     TCHAR *tmpStr = DuplicateString( ptr );
  772.     TCHAR *tmpPtr = tmpStr + lstrlen(tmpStr);
  773.     tmpPtr--;
  774.     while( tmpPtr>= tmpStr && 
  775.          (*tmpPtr == TEXT(' ')  || *tmpPtr == TEXT('t')) ||
  776.          (*tmpPtr == TEXT('n') || *tmpPtr == TEXT('r'))
  777.          ) tmpPtr--;
  778.     tmpPtr++;
  779.     *tmpPtr = TEXT('');
  780.     StrCpy( str, tmpStr );
  781.     
  782.     LocalFree( tmpStr );
  783.     return str;
  784. }
  785. BOOL FreeAssociations( )
  786. {
  787.     if( assocList == (HDPA)NULL ) return FALSE;
  788.     int assocCount = DPA_GetPtrCount( assocList );
  789.     for(int i=0; i<assocCount; i++ )
  790.     {
  791.         CAssoc * ptr = (CAssoc *)DPA_FastGetPtr( assocList, i );
  792.         if(ptr) delete ptr;
  793.     }
  794.     DPA_Destroy( assocList );
  795.     assocList = (HDPA)NULL;
  796.     return TRUE;
  797. }
  798. BOOL LoadAssociations( )
  799. {
  800.     HKEY hKey;
  801.     int index = 0;
  802.     DWORD dwLen  = MAX_PATH;
  803.     if(assocList) 
  804.         FreeAssociations();
  805.     if((assocList = DPA_Create(4)) == (HDPA)NULL ) 
  806.         return FALSE;
  807.     TCHAR * buffer = (TCHAR *)LocalAlloc( LPTR, (MAX_PATH+1)*sizeof(TCHAR) );
  808.     TCHAR * tmpKey = (TCHAR *)LocalAlloc( LPTR, (MAX_PATH+MAX_PATH+2)*sizeof(TCHAR) );
  809.     while( buffer && tmpKey )
  810.     {
  811.         dwLen  = (MAX_PATH+sizeof(g_szCmndSubKey)+2)*sizeof(TCHAR); 
  812.         if( RegEnumKeyEx( HKEY_CLASSES_ROOT, index, buffer, &dwLen,
  813.                               NULL, NULL, NULL, NULL )
  814.                 == ERROR_NO_MORE_ITEMS ) break;
  815.         {
  816.             // Skip Extensions and *.
  817.             if( *buffer == TEXT('.') || *buffer == TEXT('*')) 
  818.             {
  819.                 index++;
  820.                 continue;
  821.             }
  822.             CAssoc * ptr = NULL;
  823.             StrCpy( tmpKey, buffer );
  824.             StrCat( tmpKey, TEXT("\"));
  825.             StrCat( tmpKey, g_szCmndSubKey);
  826.             LONG lResult = RegOpenKeyEx(
  827.                     HKEY_CLASSES_ROOT,
  828.                     tmpKey,
  829.                     0,       
  830.                     KEY_QUERY_VALUE | KEY_READ,
  831.                     &hKey);
  832.             if( lResult == ERROR_SUCCESS )
  833.             {
  834.                 ptr=new CAssoc(buffer);
  835.                 if( ptr->Load() == TRUE ) 
  836.                     DPA_InsertPtr( assocList, 0x7FFF, (LPVOID)ptr);
  837.                 else 
  838.                 {
  839.                     delete ptr;
  840.                     ptr = NULL;
  841.                 }
  842.                 RegCloseKey( hKey ); 
  843.             }
  844.    
  845.             // Check if this association needs to be protected.
  846.             //  - uses DDE
  847.             //  - has clsid
  848.             //  - has protected key.
  849.             if(ptr)
  850.             {
  851.                 StrCpy(tmpKey, buffer);
  852.                 StrCat(tmpKey, TEXT("\shell\open\ddeexec") );
  853.                 // wnsprintf(tmpKey, ARRAYSIZE(tmpKey), TEXT("%s\shell\open\ddeexec"), buffer);
  854.                 lResult = RegOpenKeyEx(
  855.                         HKEY_CLASSES_ROOT,
  856.                         tmpKey,
  857.                         0,
  858.                         KEY_QUERY_VALUE | KEY_READ,
  859.                         &hKey);
  860.                 if( lResult == ERROR_SUCCESS )
  861.                 {
  862.                     ptr->m_safe = TRUE;
  863.                     RegCloseKey( hKey );
  864.                     goto Cont;
  865.                 }
  866.                 StrCpy(tmpKey, buffer);
  867.                 StrCat(tmpKey, TEXT("\clsid") );
  868.                 //wnsprintf(tmpKey, ARRAYSIZE(tmpKey), TEXT("%s\clsid"), buffer);
  869.                 lResult = RegOpenKeyEx(
  870.                         HKEY_CLASSES_ROOT,
  871.                         tmpKey,
  872.                         0,
  873.                         KEY_QUERY_VALUE | KEY_READ,
  874.                         &hKey);
  875.                 if( lResult == ERROR_SUCCESS )
  876.                 {
  877.                     ptr->m_safe = TRUE;
  878.                     RegCloseKey( hKey );
  879.                     goto Cont;
  880.                 }
  881.                 StrCpy(tmpKey, buffer);
  882.                 StrCat(tmpKey, TEXT("\protected") );
  883.                 // wnsprintf(tmpKey, ARRAYSIZE(tmpKey), TEXT("%s\protected"), buffer);
  884.                 lResult = RegOpenKeyEx(
  885.                         HKEY_CLASSES_ROOT,
  886.                         tmpKey,
  887.                         0,
  888.                         KEY_QUERY_VALUE | KEY_READ,
  889.                         &hKey);
  890.                 if( lResult == ERROR_SUCCESS )
  891.                 {
  892.                     ptr->m_safe = TRUE;
  893.                     RegCloseKey( hKey );
  894.                 }
  895.             }
  896. Cont:
  897.             index++;
  898.         }
  899.     }
  900.     if( tmpKey ) LocalFree( tmpKey );
  901.     if( buffer ) LocalFree( buffer );
  902.     return TRUE;
  903. }
  904. BOOL FreeMimeTypes( )
  905. {
  906.     if( mimeList == NULL ) return FALSE;
  907.     int mimeCount = DPA_GetPtrCount( mimeList );
  908.     for(int i=0; i<mimeCount; i++ )
  909.     {
  910.         CMime * ptr = (CMime *)DPA_FastGetPtr( mimeList, i );
  911.         if(ptr) delete ptr;
  912.     }
  913.     
  914.     DPA_Destroy( mimeList );
  915.     mimeList = (HDPA)NULL;
  916.     return TRUE;
  917. }
  918. BOOL LoadMimeTypes( )
  919. {
  920.     HKEY hKeyMime, hKey;
  921.     int index = 0;
  922.     DWORD dwLen  = MAX_PATH;
  923.     if(mimeList) FreeMimeTypes();
  924.     if((mimeList = DPA_Create(4)) == (HDPA)NULL) return FALSE;
  925.     // TODO : Get Max length of the key from registry and use it
  926.     // instead of MAX_PATH.
  927.     TCHAR * buffer = (TCHAR *)LocalAlloc( LPTR, (MAX_PATH+1)*sizeof(TCHAR) );
  928.     LONG lResult = RegOpenKeyEx(
  929.                 HKEY_CLASSES_ROOT,
  930.                 g_szMimeKey,
  931.                 0,
  932.                 KEY_QUERY_VALUE | KEY_READ,
  933.                 &hKeyMime);
  934.     
  935.     if( lResult == ERROR_SUCCESS )
  936.     {
  937.     while( buffer )
  938.     {
  939.         dwLen  = MAXPATH;
  940.         if( RegEnumKeyEx( hKeyMime, index, buffer, &dwLen,
  941.                               NULL, NULL, NULL, NULL )
  942.                 == ERROR_NO_MORE_ITEMS ) break;
  943.         {
  944.             CMime * ptr = new CMime( buffer );
  945.             lResult = RegOpenKeyEx(
  946.                     hKeyMime,
  947.                     buffer,
  948.                     0,
  949.                     KEY_QUERY_VALUE | KEY_READ,
  950.                     &hKey);
  951.             if( lResult == ERROR_SUCCESS )
  952.             {
  953.                 dwLen = MAX_PATH;
  954.                 if (RegQueryValue( hKey, TEXT("extension"), buffer,  (long *)&dwLen ) 
  955.                     == ERROR_SUCCESS )
  956.                 {
  957.                     ptr->m_exts = (TCHAR *)LocalAlloc( LPTR, (dwLen+1)*sizeof(TCHAR));
  958.                     StrCpy(ptr->m_exts, buffer);
  959.                 }
  960.                 
  961.                 RegCloseKey( hKey );
  962.             }
  963.             DPA_InsertPtr(mimeList, 0x7FFF, (LPVOID)ptr);
  964.             index++;
  965.         }
  966.     }
  967.     RegCloseKey( hKeyMime );
  968.     }
  969.     if( buffer ) LocalFree( buffer );
  970.     return TRUE;
  971. }
  972. BOOL PrintAssociations()
  973. {
  974.     printf("Listing Associations:n");
  975.     if( !assocList ) return FALSE;
  976.     int assocCount = DPA_GetPtrCount( assocList );
  977.     for(int i=0; i<assocCount; i++ )
  978.     {
  979.        CAssoc * ptr = (CAssoc *)DPA_FastGetPtr( assocList, i );
  980.        ptr->Print();
  981.     }
  982.     return TRUE;
  983. }
  984. BOOL FindCommand(HWND hDlg)
  985. {
  986.     TCHAR szFile[MAX_PATH] = TEXT("");
  987.     TCHAR szFilter[5];
  988.     OPENFILENAME ofn;
  989.     HWND hCmnd = GetDlgItem(hDlg, IDC_DOC_CMND );
  990.     memset((void*)&szFilter, 0, 5*sizeof(TCHAR));
  991.     szFilter[0] = TCHAR('*');
  992.     szFilter[2] = TCHAR('*');
  993.     memset((void*)&ofn, 0, sizeof(ofn));
  994.     ofn.lpstrFilter = szFilter;
  995.     ofn.lStructSize = sizeof(ofn);
  996.     ofn.hwndOwner = hDlg;
  997.     ofn.lpstrFile = szFile;
  998.     ofn.nMaxFile = MAX_PATH;
  999.     ofn.lpstrInitialDir = NULL;
  1000.     ofn.Flags = OFN_HIDEREADONLY|OFN_CREATEPROMPT;
  1001.     if (GetOpenFileName(&ofn))
  1002.     {
  1003.         SendMessage(hCmnd, EM_SETSEL, 0, -1);
  1004.         SendMessage(hCmnd, EM_REPLACESEL, 0, (LPARAM)szFile);
  1005.     }
  1006.     return TRUE;
  1007. }
  1008. int FindIndex(LPTSTR doc)
  1009. {
  1010.     if( ! assocList ) return -1;
  1011.     int assocCount = DPA_GetPtrCount( assocList );
  1012.     for(int i = 0; i< assocCount;i++ )
  1013.     {
  1014.         CAssoc * ptr = (CAssoc *)DPA_FastGetPtr( assocList, i );
  1015.         if( !StrCmp(doc, ptr->m_type ) )
  1016.             return i;
  1017.     }
  1018.     return -1;
  1019. }
  1020. HDPA CreateDPAForExts( TCHAR * strPassed, int * error, CAssoc * existing)
  1021. {
  1022.     HKEY hKey;
  1023.     int  bFound = 0;
  1024.     HDPA hdpaExts = NULL;
  1025.     // Check for existing associations not created by IEUNIX
  1026.     // [.ext
  1027.     //   (--reg-val--  "Application")
  1028.     //   (content.type "mimetype"   )
  1029.     //   (g_szIEUnix   "g_szIEUnixTag" )
  1030.     // ]
  1031.     EatSpaces(strPassed);
  1032.     if(strPassed && *strPassed)
  1033.     {
  1034.         TCHAR *strExt = DuplicateString( strPassed );
  1035.         TCHAR *pos, *ptr = strExt;
  1036.         BOOL  bCont = TRUE;
  1037.          
  1038.         while(bCont && *ptr)
  1039.         {   
  1040.             pos = StrChr(ptr, TEXT(';'));
  1041.             if(pos)
  1042.             {
  1043.                 bCont = ( *pos == TEXT(';') )? TRUE : FALSE;
  1044.                 *pos = TEXT('');
  1045.             }
  1046.             else
  1047.             {
  1048.                bCont = FALSE;
  1049.             }
  1050.              
  1051.             if( !hdpaExts ) hdpaExts = DPA_Create(4);
  1052.             DPA_InsertPtr( hdpaExts, 0x7FFF, (LPVOID)DuplicateString( ptr ) );
  1053.             if(*ptr == TEXT('.') && *(ptr+1) )
  1054.             {
  1055.                 int  assocCount, extCount;
  1056.                 assocCount = DPA_GetPtrCount( assocList );
  1057.                 for( int i = 0; i< assocCount; i++ )
  1058.                 {
  1059.                     CAssoc * pAssoc = (CAssoc*)DPA_FastGetPtr( assocList, i );
  1060.                     
  1061.                     if( pAssoc->m_exts == NULL || pAssoc == existing ) continue;
  1062.                     extCount = DPA_GetPtrCount(pAssoc->m_exts) ;
  1063.                     for(int j=0;j<extCount;j++ )
  1064.                     {
  1065.                        if( !StrCmpI(ptr, (LPTSTR)DPA_FastGetPtr( pAssoc->m_exts, j ) ) )
  1066.                        {
  1067.                           bFound = IDS_ERROR_EXTS_ALREADY_EXISTS;
  1068.                           break;
  1069.                        }
  1070.                     }
  1071.                    
  1072.                     if( bFound ) break;
  1073.                 }
  1074.             }
  1075.             else
  1076.             {
  1077.                 // Extension must start with a '.'
  1078.                 bFound = IDS_ERROR_NOT_AN_EXT;
  1079.                 break;
  1080.             }
  1081.             ptr = pos+1;
  1082.         }
  1083.         if(strExt) LocalFree(strExt);
  1084.     } 
  1085.     else
  1086.         bFound = IDS_ERROR_MISSING_EXTS;
  1087.     *error = bFound;
  1088.     // Error occured while checking extensions
  1089.     if( bFound )
  1090.     {
  1091.         if(hdpaExts) FreeExtensions( hdpaExts );
  1092.         return NULL;
  1093.     }
  1094.     return hdpaExts;
  1095. }
  1096. // Following functions are called in response to the 
  1097. // actions performed on the associations.
  1098. AssocDel( HWND hDlg )
  1099. {
  1100.     int index    = 0;
  1101.     int lbindex  = 0;
  1102.     HWND lb      = GetDlgItem( hDlg, IDC_DOC_LIST );
  1103.     if( (lbindex = SendMessage( lb, LB_GETCURSEL, 0, 0 ) )!= LB_ERR )
  1104.     {
  1105.         LPTSTR str = (LPTSTR)SendMessage(lb, LB_GETITEMDATA, lbindex, 0 );
  1106.         if(str)
  1107.         {
  1108.             if( (index = FindIndex( str ) ) != -1 )
  1109.             {
  1110.                  CAssoc * ptr = (CAssoc *)DPA_FastGetPtr( assocList, index );
  1111.                  TCHAR question[MAX_PATH];
  1112.                  wnsprintf( question, ARRAYSIZE(question), TEXT("Are you Sure you want to delete '%s'?"), ptr->m_desc );
  1113.                  if( MessageBox( GetParent(hDlg), question, TEXT("Delete Association"), MB_YESNO ) == IDYES )
  1114.                  {
  1115.                      CAssoc *pAssoc = (CAssoc *)DPA_DeletePtr( assocList, index );
  1116.                     // Add to List of deleted entries
  1117.                     if( assocDelList == NULL ) assocDelList = DPA_Create(4);
  1118.                     if( assocDelList != NULL ) DPA_InsertPtr( assocDelList, 0x7FFF, pAssoc );
  1119.                     SendMessage( lb, LB_DELETESTRING, lbindex, 0 );
  1120.                     InitAssocDialog( hDlg ); 
  1121.                     SwitchToNrmlMode( hDlg );
  1122.                     PropSheet_Changed(GetParent(hDlg),hDlg);
  1123.                     LocalFree( str );
  1124.                 } 
  1125.             }
  1126.         }
  1127.     }
  1128.     return TRUE;
  1129. }
  1130. #ifdef 0
  1131. AssocUpd( HWND hDlg )
  1132. {
  1133.     BOOL bFound = FALSE;
  1134.     TCHAR szTemp [1024];
  1135.     TCHAR szTitle [80];
  1136.     CAssoc *ptr = NULL;
  1137.     TCHAR *str;
  1138.     int    index, len;
  1139.     HDPA   hdpaExts = NULL;
  1140.     HWND lb   = GetDlgItem( hDlg, IDC_DOC_LIST );
  1141.     HWND exts = GetDlgItem( hDlg, IDC_DOC_EXTS );
  1142.     HWND desc = GetDlgItem( hDlg, IDC_DOC_DESC );
  1143.     HWND mime = GetDlgItem( hDlg, IDC_DOC_MIME );
  1144.     HWND cmnd = GetDlgItem( hDlg, IDC_DOC_CMND );
  1145.     MLLoadString(IDS_ERROR_REGISTRY_TITLE, szTitle, sizeof(szTitle));
  1146.     // Get the pointer to existing associations.
  1147.     if(PGTI_FROM_HDLG(hDlg)->mode == UPDATING)
  1148.     {
  1149.          ptr = GetCurrentAssoc( hDlg );
  1150.     }
  1151.     //Check for Description
  1152.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_DESC), WM_GETTEXTLENGTH, 0, 0 );
  1153.     if( len > 0 )
  1154.     {
  1155.         str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1156.         SendMessage(GetDlgItem(hDlg, IDC_DOC_DESC), WM_GETTEXT, len+1, (LPARAM)str );
  1157.         ChopSpaces( str );
  1158.         if( *str == TEXT('') )
  1159.         {    
  1160.             LocalFree(str);
  1161.             MLLoadString(IDS_ERROR_MISSING_DESC, szTemp, sizeof(szTemp));
  1162.             MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1163.             SetFocus( GetDlgItem(hDlg, IDC_DOC_DESC) );
  1164.             return FALSE;
  1165.         }
  1166.         int assocCount = DPA_GetPtrCount( assocList );
  1167.         for( int i= 0; i<assocCount; i++ )
  1168.         {
  1169.             CAssoc * pAssoc ;
  1170.             if((pAssoc= (CAssoc *)DPA_FastGetPtr( assocList, i )) == ptr ) continue;
  1171.             
  1172.             if( StrCmpI( str, pAssoc->m_cmnd ) == NULL )
  1173.             {
  1174.                 LocalFree(str);
  1175.                 MLLoadString(IDS_ERROR_DESC_ALREADY_EXISTS, szTemp, sizeof(szTemp));
  1176.                 MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1177.                 SetFocus( GetDlgItem(hDlg, IDC_DOC_DESC) );
  1178.                 return FALSE;
  1179.             }
  1180.         }
  1181.         LocalFree(str);
  1182.     }
  1183.     else
  1184.     {
  1185.         MLLoadString(IDS_ERROR_MISSING_DESC, szTemp, sizeof(szTemp));
  1186.         MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1187.         SetFocus( GetDlgItem(hDlg, IDC_DOC_DESC) );
  1188.         return FALSE;
  1189.     }
  1190.     //Check for MIME
  1191.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_MIME), WM_GETTEXTLENGTH, 0, 0 );
  1192.     if( len > 0 )
  1193.     {
  1194.         str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1195.         SendMessage(GetDlgItem(hDlg, IDC_DOC_MIME), WM_GETTEXT, len+1, (LPARAM)str );
  1196.         ChopSpaces( str );
  1197.         if( *str != TEXT('') )
  1198.         {
  1199.             if( !StrChr( str, TEXT('/') ) )
  1200.             {
  1201.                 LocalFree(str);
  1202.                 MLLoadString(IDS_ERROR_INVALID_MIME, szTemp, sizeof(szTemp));
  1203.                 MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1204.                 SetFocus( GetDlgItem(hDlg, IDC_DOC_MIME) );
  1205.                 return FALSE;
  1206.             }
  1207.         }
  1208.         LocalFree(str);
  1209.     }
  1210.     
  1211.     //Check for command line
  1212.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_CMND), WM_GETTEXTLENGTH, 0, 0 );
  1213.     if( len > 0 )
  1214.     {
  1215.         str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1216.         SendMessage(GetDlgItem(hDlg, IDC_DOC_CMND), WM_GETTEXT, len+1, (LPARAM)str );
  1217.         ChopSpaces( str );
  1218.         if( *str == TEXT('') )
  1219.         {
  1220.             LocalFree(str);
  1221.             MLLoadString(IDS_ERROR_MISSING_CMND, szTemp, sizeof(szTemp));
  1222.             MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1223.             SetFocus( GetDlgItem(hDlg, IDC_DOC_CMND) );
  1224.             return FALSE;
  1225.         }    
  1226.         LocalFree(str);
  1227.     }
  1228.     else
  1229.     {
  1230.         MLLoadString(IDS_ERROR_MISSING_CMND, szTemp, sizeof(szTemp));
  1231.         MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1232.         SetFocus( GetDlgItem(hDlg, IDC_DOC_CMND) );
  1233.         return FALSE;
  1234.     }
  1235.     // Check for extensions.
  1236.     // User entered may already have associations in the
  1237.     // registry.
  1238.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_EXTS), WM_GETTEXTLENGTH, 0, 0 );
  1239.     str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1240.     SendMessage(GetDlgItem(hDlg, IDC_DOC_EXTS), WM_GETTEXT, len+1, (LPARAM)str );
  1241.     int error;
  1242.     if(!(hdpaExts = CreateDPAForExts(EatSpaces(str), &error, ptr)))
  1243.     {
  1244.         LocalFree( str );
  1245.         MLLoadString(error, szTemp, sizeof(szTemp));
  1246.         MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1247.         SetFocus( GetDlgItem(hDlg, IDC_DOC_EXTS) );
  1248.         return FALSE;
  1249.     }
  1250.     LocalFree( str );
  1251.   
  1252.     // Check and Add CAssoc if we are inserting a new entry.
  1253.     if(PGTI_FROM_HDLG(hDlg)->mode == ADDING)
  1254.     {
  1255.          LPTSTR firstExt = (LPTSTR)DPA_FastGetPtr( hdpaExts, 0 );
  1256.          int len = lstrlen( firstExt ) + lstrlen(g_szDocClass) + 1;
  1257.          str = (TCHAR *)LocalAlloc( LPTR, len*sizeof(TCHAR) );
  1258.          StrCpy( str, firstExt+1   );
  1259.          StrCat( str, g_szDocClass );
  1260.          ptr = new CAssoc( str );
  1261.          ptr->m_safe = FALSE; // Since we are adding this entry.
  1262.          DPA_InsertPtr( assocList, 0x7FFF, ptr );
  1263.          LocalFree( str );
  1264.     }
  1265.     // We are not able to add or retrieve Assoc from the List
  1266.     if( ptr == NULL || ptr->m_safe == TRUE )
  1267.     {
  1268.         FreeExtensions( hdpaExts );
  1269.         return FALSE;
  1270.     }
  1271.     // Start replacing components of the Associations.
  1272.     // Replace Extensions
  1273.     if(ptr->m_exts) FreeExtensions( ptr->m_exts );
  1274.     ptr->m_exts = hdpaExts;
  1275.  
  1276.     // Replace mime type
  1277.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_MIME), WM_GETTEXTLENGTH, 0, 0 );
  1278.     str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1279.     SendMessage(GetDlgItem(hDlg, IDC_DOC_MIME), WM_GETTEXT, len+1, (LPARAM)str );
  1280.     if( ptr->m_mime ) LocalFree( ptr->m_mime );
  1281.     ptr->m_mime = EatSpaces(str);
  1282.     // Replace Description
  1283.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_DESC), WM_GETTEXTLENGTH, 0, 0 );
  1284.     str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1285.     SendMessage(GetDlgItem(hDlg, IDC_DOC_DESC), WM_GETTEXT, len+1, (LPARAM)str );
  1286.     if( ptr->m_desc ) LocalFree( ptr->m_desc);
  1287.     ptr->m_desc = ChopSpaces(str);
  1288.     // Replace Command Line
  1289.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_CMND), WM_GETTEXTLENGTH, 0, 0 );
  1290.     str = (TCHAR *)LocalAlloc( LPTR, (len+4)*sizeof(TCHAR) );
  1291.     SendMessage(GetDlgItem(hDlg, IDC_DOC_CMND), WM_GETTEXT, len+1, (LPARAM)str );
  1292.     if( ptr->m_cmnd ) LocalFree( ptr->m_cmnd );
  1293.     ptr->m_cmnd = ChopSpaces(str);
  1294.     if (ptr->m_stat == NEW)
  1295. if (!StrStr(ptr->m_cmnd, TEXT("%1")))
  1296.     lstrcat(ptr->m_cmnd, TEXT(" %1"));
  1297.     {
  1298.         DWORD dwCurChar;
  1299.         BOOL  bPath = FALSE;
  1300.     
  1301.         for (dwCurChar = 0; dwCurChar < lstrlen(ptr->m_cmnd); dwCurChar++)
  1302.         {
  1303.     if (ptr->m_cmnd[dwCurChar] == TEXT('/'))
  1304.             {
  1305. bPath = TRUE;
  1306.     }
  1307.     if (ptr->m_cmnd[dwCurChar] == TEXT(' '))
  1308.             {
  1309. break;
  1310.     }
  1311. }
  1312. if (bPath)  // if it's file name with no path we assume it's in the user's PATH
  1313.     {    
  1314.         CHAR szExeFile[MAX_PATH];
  1315.         TCHAR szWarning[MAX_PATH + 128];
  1316. #ifndef UNICODE
  1317.         lstrcpyn(szExeFile, ptr->m_cmnd, dwCurChar + 1);
  1318. #else
  1319.         WCHAR wszExeFile[MAX_PATH];
  1320.         lstrcpyn(wszExeFile, ptr->m_cmnd, dwCurChar + 1);
  1321.         SHUnicodeToAnsi(wszExeFile, szExeFile, ARRAYSIZE(szExeFile));
  1322. #endif
  1323.         if (access(szExeFile, X_OK) != 0)
  1324.     {
  1325. #ifndef UNICODE
  1326.             wsprintf(szWarning, TEXT("File %s is not an executable file."), szExeFile);
  1327. #else
  1328.             wsprintf(szWarning, TEXT("File %s is not an executable file."), wszExeFile);
  1329. #endif
  1330.     MessageBox( GetParent(hDlg), szWarning, TEXT("Warning"), MB_OK);
  1331.     }
  1332. }
  1333.     }
  1334.     if (Button_GetCheck(GetDlgItem(hDlg, IDC_ASSOC_EDIT)) != BST_UNCHECKED)
  1335.        ptr->m_edit &= (~FTA_OpenIsSafe );
  1336.     else
  1337.        ptr->m_edit |= FTA_OpenIsSafe;
  1338.     ptr->m_stat = UPD;
  1339.     InitAssocDialog( hDlg, ptr );
  1340.     SwitchToNrmlMode( hDlg);
  1341.     
  1342.     // SetFocus to Ok button again
  1343.     SetFocus( GetDlgItem(GetParent( hDlg ), IDOK ) );
  1344.     PropSheet_Changed(GetParent(hDlg),hDlg);
  1345.     return TRUE;
  1346. }
  1347. AssocAdd( HWND hDlg)
  1348. {
  1349.     SwitchToAddMode( hDlg );
  1350.     PropSheet_Changed(GetParent(hDlg),hDlg);
  1351.     return TRUE;
  1352. }
  1353. #endif // 0
  1354. CAssoc * GetCurrentAssoc( HWND hDlg )
  1355. {
  1356.     int index = 0;
  1357.     HWND lb   = GetDlgItem( hDlg, IDC_DOC_LIST );
  1358.     if( (index = SendMessage( lb, LB_GETCURSEL, 0, 0 ) )!= LB_ERR )
  1359.     {
  1360.         TCHAR * str = (LPTSTR)SendMessage( lb, LB_GETITEMDATA, index, 0 );
  1361.         if(!str) return NULL;
  1362.         if(str && *str)
  1363.         {
  1364.             if( (index = FindIndex( str ) ) != -1 )
  1365.             {
  1366.                 CAssoc * ptr = (CAssoc *)DPA_FastGetPtr( assocList, index );
  1367.                 return ptr;
  1368.             }
  1369.         }
  1370.     }
  1371.     return NULL;
  1372. }
  1373. SwitchToNrmlMode( HWND hDlg )
  1374. {
  1375.     PGTI_FROM_HDLG(hDlg)->mode = NORMAL;
  1376.     EnableWindow(GetDlgItem(hDlg,IDC_DOC_DESC), FALSE );
  1377.     EnableWindow(GetDlgItem(hDlg,IDC_DOC_EXTS), FALSE );
  1378.     EnableWindow(GetDlgItem(hDlg,IDC_DOC_MIME), FALSE );
  1379.     EnableWindow(GetDlgItem(hDlg,IDC_DOC_CMND), FALSE );
  1380.     EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_EDIT), FALSE );
  1381.     if (IsAssocEnabled())
  1382.     {
  1383. CAssoc *pAssoc = GetCurrentAssoc( hDlg );
  1384.         EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_ADD), TRUE );
  1385. if( pAssoc ) 
  1386.         {
  1387.     if( pAssoc->m_safe )
  1388.     {
  1389. EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_DEL), FALSE);
  1390. EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_UPD), FALSE );
  1391.     }
  1392.     else
  1393.     {
  1394. EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_DEL), TRUE );
  1395. EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_UPD), TRUE );
  1396.     }
  1397. }
  1398.     }
  1399.     else
  1400.     {
  1401.         EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_DEL), FALSE);
  1402.         EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_UPD), FALSE );
  1403.         EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_ADD), FALSE );
  1404.     }
  1405.     REMOVE_DEF_BORDER(hDlg, IDC_ASSOC_ADD );
  1406.     REMOVE_DEF_BORDER(hDlg, IDC_ASSOC_UPD );
  1407.     REMOVE_DEF_BORDER(hDlg, IDC_ASSOC_DEL );
  1408.     SET_DEF_BORDER( GetParent(hDlg), IDOK );
  1409.     return TRUE;
  1410. }
  1411. SwitchToAddMode( HWND hDlg )
  1412. {
  1413.     PGTI_FROM_HDLG(hDlg)->mode = ADDING;
  1414.     LPASSOCTABINFO pgti = (LPASSOCTABINFO)GetWindowLong(hDlg, DWL_USER);
  1415.     // Remove Selection from Listbox.
  1416.     SendMessage( GetDlgItem(hDlg, IDC_DOC_LIST), LB_SETCURSEL,
  1417.            (WPARAM)-1, 0);
  1418.     pgti->fInternalChange = TRUE;
  1419.     
  1420.     // Clear all the fields
  1421.     SendMessage( GetDlgItem(hDlg, IDC_DOC_DESC), WM_SETTEXT,
  1422.            0, LPARAM( TEXT("")) );
  1423.     SendMessage( GetDlgItem(hDlg, IDC_DOC_MIME), WM_SETTEXT,
  1424.            0, LPARAM( TEXT("")) );
  1425.     SendMessage( GetDlgItem(hDlg, IDC_DOC_EXTS), WM_SETTEXT,
  1426.            0, LPARAM( TEXT("")) );
  1427.     SendMessage( GetDlgItem(hDlg, IDC_DOC_CMND), WM_SETTEXT,
  1428.            0, LPARAM( TEXT("")) );
  1429.     
  1430.     // Default value
  1431.     Button_SetCheck( GetDlgItem( hDlg, IDC_ASSOC_EDIT),  TRUE ); 
  1432.     pgti->fInternalChange = FALSE;
  1433.     // Enable all edit windows
  1434.     EnableWindow(GetDlgItem(hDlg,IDC_DOC_DESC), TRUE);
  1435.     EnableWindow(GetDlgItem(hDlg,IDC_DOC_MIME), TRUE);
  1436.     EnableWindow(GetDlgItem(hDlg,IDC_DOC_EXTS), TRUE);
  1437.     EnableWindow(GetDlgItem(hDlg,IDC_DOC_CMND), TRUE);
  1438.     EnableWindow(GetDlgItem(hDlg,IDC_BROWSE  ), TRUE);
  1439.     EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_EDIT  ), TRUE);
  1440.     // Enable Add option
  1441.     EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_ADD), FALSE);
  1442.     EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_UPD), TRUE );
  1443.     EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_DEL), FALSE);
  1444.     // Remove Default Border
  1445.     REMOVE_DEF_BORDER( GetParent(hDlg), IDOK );
  1446.     REMOVE_DEF_BORDER( hDlg, IDC_ASSOC_ADD);
  1447.     REMOVE_DEF_BORDER( hDlg, IDC_ASSOC_DEL);
  1448.     SET_DEF_BORDER( hDlg, IDC_ASSOC_UPD );
  1449.     SetFocus( GetDlgItem( hDlg, IDC_ASSOC_UPD ) );
  1450.     return TRUE;
  1451. }
  1452. SwitchToUpdMode( HWND hDlg )
  1453. {
  1454.     if(PGTI_FROM_HDLG(hDlg)->mode != NORMAL )
  1455.        return FALSE;
  1456.     PGTI_FROM_HDLG(hDlg)->mode = UPDATING;
  1457.     // Enable Upd option
  1458.     EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_ADD), TRUE );
  1459.     EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_UPD), TRUE );
  1460.     EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_DEL), TRUE );
  1461.     // Remove Default Border
  1462.     REMOVE_DEF_BORDER( GetParent(hDlg), IDOK );
  1463.     REMOVE_DEF_BORDER( hDlg, IDC_ASSOC_ADD);
  1464.     REMOVE_DEF_BORDER( hDlg, IDC_ASSOC_DEL);
  1465.     SET_DEF_BORDER( hDlg, IDC_ASSOC_UPD);
  1466.     return TRUE;
  1467. }
  1468. void ListBoxResetContents(HWND listBox)
  1469. {
  1470.     int count = SendMessage( listBox, LB_GETCOUNT, 0, 0 );
  1471.     for( int i= 0; i< count; i++ )
  1472.     {
  1473.         LPSTR data = (LPSTR)SendMessage( listBox, LB_GETITEMDATA, i, 0 );
  1474.         if( data ) LocalFree( data );
  1475.     }
  1476.     SendMessage( listBox, LB_RESETCONTENT, 0, 0 );
  1477. }
  1478. BOOL FAR PASCAL InitAssocDialog(HWND hDlg, CAssoc * current)
  1479. {
  1480.     HRESULT  hr = E_FAIL;
  1481.     HKEY     hKey;
  1482.     HWND     listBox = GetDlgItem( hDlg, IDC_DOC_LIST );
  1483.     TCHAR *  displayString;
  1484.     // Allocate memory for a structure which will hold all the info
  1485.     // gathered from this page
  1486.     //
  1487.     LPASSOCTABINFO pgti = (LPASSOCTABINFO)GetWindowLong(hDlg, DWL_USER);
  1488.     pgti->fInternalChange = FALSE;
  1489.     ListBoxResetContents( listBox );
  1490.     if( assocList == NULL ) return FALSE;
  1491.     int assocCount = DPA_GetPtrCount( assocList );
  1492.     for(int i = 0; i< assocCount; i++ )
  1493.     {
  1494.         CAssoc * ptr = (CAssoc *)DPA_FastGetPtr( assocList, i );
  1495.         int index = SendMessage( listBox, LB_ADDSTRING, 0, (LPARAM)ptr->m_desc );
  1496.         SendMessage( listBox, LB_SETITEMDATA, index, (LPARAM)DuplicateString( ptr->m_type ) );
  1497.     }
  1498.     if( i>0 )
  1499.         SendMessage( listBox, LB_SETCURSEL, 0, 0 );
  1500.     else
  1501.     {
  1502.         SendMessage( GetDlgItem(hDlg, IDC_DOC_DESC), WM_SETTEXT,
  1503.            0, LPARAM( TEXT("")) );
  1504.         SendMessage( GetDlgItem(hDlg, IDC_DOC_MIME), WM_SETTEXT,
  1505.            0, LPARAM( TEXT("")) );
  1506.         SendMessage( GetDlgItem(hDlg, IDC_DOC_EXTS), WM_SETTEXT,
  1507.            0, LPARAM( TEXT("")) );
  1508.         SendMessage( GetDlgItem(hDlg, IDC_DOC_CMND), WM_SETTEXT,
  1509.            0, LPARAM( TEXT("")) );
  1510.         // Default value
  1511.         Button_SetCheck( GetDlgItem( hDlg, IDC_ASSOC_EDIT),  TRUE ); 
  1512.     }
  1513.     // Add Strings to Mimetype dialog
  1514.     int mimeCount = 0;
  1515.     if( mimeList && (mimeCount = DPA_GetPtrCount(mimeList)))
  1516.     {
  1517.         for(i=0; i< mimeCount; i++)
  1518.         {
  1519.             CMime * ptr = (CMime *)DPA_FastGetPtr( mimeList , i );
  1520.     SafeAddStringToComboBox( GetDlgItem(hDlg, IDC_DOC_MIME) , ptr->m_mime) ;
  1521.         }   
  1522.     }
  1523.     if( current )
  1524.         SendMessage( listBox, LB_SELECTSTRING, -1, (LPARAM)current->m_desc );
  1525.     HandleSelChange( pgti );
  1526.     SwitchToNrmlMode( hDlg );
  1527.     if( IsAssocEnabled() && i > 0 )
  1528.         EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_DEL), TRUE);
  1529.     else
  1530.         EnableWindow(GetDlgItem(hDlg,IDC_ASSOC_DEL), FALSE);
  1531.     return TRUE;
  1532. }
  1533. void HandleSelChange( LPASSOCTABINFO pgti, BOOL bApplChange )
  1534. {
  1535.     int index = 0;
  1536.     HWND hDlg = pgti->hDlg;
  1537.     TCHAR str[MAX_PATH] = TEXT("");
  1538.     if( hDlg == NULL ) return;
  1539.     HWND exts = GetDlgItem( hDlg, IDC_DOC_EXTS );
  1540.     HWND desc = GetDlgItem( hDlg, IDC_DOC_DESC );
  1541.     HWND mime = GetDlgItem( hDlg, IDC_DOC_MIME );
  1542.     HWND cmnd = GetDlgItem( hDlg, IDC_DOC_CMND );
  1543.     HWND brws = GetDlgItem( hDlg, IDC_BROWSE   );
  1544.     HWND edit = GetDlgItem( hDlg, IDC_ASSOC_EDIT );
  1545.     CAssoc * ptr = GetCurrentAssoc( hDlg );
  1546.  
  1547.     if(ptr)
  1548.     {
  1549.         SendMessage( desc, WM_SETTEXT, 0, (LPARAM)ptr->m_desc );
  1550.         SendMessage( mime, WM_SETTEXT, 0, (LPARAM)ptr->m_mime );
  1551.         SendMessage( cmnd, WM_SETTEXT, 0, (LPARAM)ptr->m_cmnd );
  1552.         // Create Extension List
  1553.         if( ptr->m_exts )
  1554.         {
  1555.             int i, count = DPA_GetPtrCount( ptr->m_exts );
  1556.             for(i=0;i<count;i++)
  1557.             {
  1558.                 StrCat( str, (LPTSTR)DPA_FastGetPtr( ptr->m_exts, i ) );
  1559.                 StrCat( str, TEXT(";") );
  1560.             }
  1561.             SendMessage( exts, WM_SETTEXT, 0, (LPARAM)str );
  1562.         }
  1563.                 
  1564.         Button_SetCheck( GetDlgItem( hDlg, IDC_ASSOC_EDIT), !(ptr->m_edit & FTA_OpenIsSafe) ); 
  1565.         EnableWindow( desc, !(ptr->m_safe) );
  1566.         EnableWindow( exts, !(ptr->m_safe) );
  1567.         EnableWindow( mime, !(ptr->m_safe) );
  1568.         EnableWindow( cmnd, !(ptr->m_safe) );
  1569.         EnableWindow( brws, !(ptr->m_safe) );
  1570.         EnableWindow( edit, !(ptr->m_safe) );
  1571.         pgti->fInternalChange = FALSE;
  1572.         // Change back to the NORMAL mode if not coming from 
  1573.         // edit.
  1574.         SwitchToNrmlMode( hDlg );
  1575.     }
  1576. }
  1577. BOOL AssocOnCommand(LPASSOCTABINFO pgti, UINT id, UINT nCmd)
  1578. {
  1579.     switch (id)
  1580.     { 
  1581.         case IDC_BROWSE:
  1582.             switch (nCmd )
  1583.             {
  1584.                case BN_CLICKED:
  1585.                {
  1586.                     FindCommand( pgti->hDlg );
  1587.                     break;
  1588.                }
  1589.             }
  1590.             break;
  1591.         case IDC_ASSOC_ADD:
  1592.             switch (nCmd )
  1593.             {
  1594.                 case BN_CLICKED:
  1595.                 {
  1596.     ENTERASSOC enter;
  1597.     enter.pgti = pgti;
  1598.     enter.pszAssoc = NULL;
  1599.     DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_ENTER_ASSOC), 
  1600.  pgti->hDlg, EnterAssocDlgProc, (LPARAM) &enter);
  1601.     InitAssocDialog( pgti->hDlg, GetCurrentAssoc( pgti->hDlg ) );
  1602.     SwitchToNrmlMode( pgti->hDlg);
  1603.     // SetFocus to Ok button again
  1604.     SetFocus( GetDlgItem(GetParent( pgti->hDlg ), IDOK ) );
  1605.     if (pgti->fChanged)
  1606.     {
  1607.         pgti->fChanged = FALSE;
  1608. PropSheet_Changed(GetParent(pgti->hDlg),pgti->hDlg);
  1609.     }
  1610.                     //AssocAdd( pgti->hDlg );
  1611.                     break;
  1612.                }
  1613.             }
  1614.             break;
  1615.         case IDC_ASSOC_UPD:
  1616.             switch (nCmd )
  1617.             {
  1618.                case BN_CLICKED:
  1619.                {
  1620.     HWND lb   = GetDlgItem( pgti->hDlg, IDC_DOC_LIST );
  1621.     int  index;
  1622.     if( (index = SendMessage( lb, LB_GETCURSEL, 0, 0 ) )!= LB_ERR )
  1623.     {
  1624.         TCHAR * str = (LPTSTR)SendMessage( lb, LB_GETITEMDATA, index, 0 );
  1625. ENTERASSOC enter;
  1626. if(!str) return FALSE;
  1627. enter.pgti = pgti;
  1628. enter.pszAssoc = str;
  1629. DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_ENTER_ASSOC), 
  1630.      pgti->hDlg, EnterAssocDlgProc, (LPARAM) &enter);
  1631. InitAssocDialog( pgti->hDlg, GetCurrentAssoc( pgti->hDlg ) );
  1632. SwitchToNrmlMode( pgti->hDlg);
  1633. // SetFocus to Ok button again
  1634. SetFocus( GetDlgItem(GetParent( pgti->hDlg ), IDOK ) );
  1635. if (pgti->fChanged)
  1636. {
  1637.     pgti->fChanged = FALSE;
  1638.     PropSheet_Changed(GetParent(pgti->hDlg),pgti->hDlg);
  1639. }
  1640.     }
  1641.                     //AssocUpd( pgti->hDlg );
  1642.                     break;
  1643.                }
  1644.             }
  1645.             break;
  1646.         case IDC_ASSOC_DEL:
  1647.             switch (nCmd )
  1648.             {
  1649.                case BN_CLICKED:
  1650.                {
  1651.                     AssocDel( pgti->hDlg ); 
  1652.                     break;
  1653.                }
  1654.             }
  1655.             break;
  1656.         case IDC_DOC_LIST:
  1657.             switch (nCmd )
  1658.             {
  1659.                 case LBN_SELCHANGE:
  1660.                      HandleSelChange( pgti );
  1661.                      break;
  1662.         case LBN_DBLCLK:
  1663.                {
  1664.     HWND lb   = GetDlgItem( pgti->hDlg, IDC_DOC_LIST );
  1665.     int  index;
  1666.     if( (index = SendMessage( lb, LB_GETCURSEL, 0, 0 ) )!= LB_ERR )
  1667.     {
  1668.         TCHAR * str = (LPTSTR)SendMessage( lb, LB_GETITEMDATA, index, 0 );
  1669. ENTERASSOC enter;
  1670. CAssoc *pAssoc = GetCurrentAssoc( pgti->hDlg );
  1671. if(!IsAssocEnabled() || pAssoc->m_safe || !str) return FALSE;
  1672. enter.pgti = pgti;
  1673. enter.pszAssoc = str;
  1674. DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_ENTER_ASSOC), 
  1675.      pgti->hDlg, EnterAssocDlgProc, (LPARAM) &enter);
  1676. InitAssocDialog( pgti->hDlg, GetCurrentAssoc( pgti->hDlg ) );
  1677. SwitchToNrmlMode( pgti->hDlg);
  1678. // SetFocus to Ok button again
  1679. SetFocus( GetDlgItem(GetParent( pgti->hDlg ), IDOK ) );
  1680. if (pgti->fChanged)
  1681. {
  1682.     pgti->fChanged = FALSE;
  1683.     PropSheet_Changed(GetParent(pgti->hDlg),pgti->hDlg);
  1684. }
  1685.     }
  1686.                     //AssocUpd( pgti->hDlg );
  1687.                     break;
  1688.                }
  1689.             }
  1690.             break;
  1691. #ifdef 0
  1692.         case IDC_DOC_MIME:
  1693.             switch (nCmd)
  1694.             {
  1695.                 case CBN_SELCHANGE:
  1696.                 case CBN_EDITCHANGE:
  1697.                     if (!pgti->fInternalChange)
  1698.                     {
  1699.                         pgti->fChanged = TRUE;
  1700.                         SwitchToUpdMode( pgti->hDlg );
  1701.                     }
  1702.                     break;
  1703.             }
  1704.             break;
  1705.         case IDC_ASSOC_EDIT:
  1706.             switch (nCmd )
  1707.             {
  1708.                case BN_CLICKED:
  1709.                {
  1710.                     if (!pgti->fInternalChange)
  1711.                     {
  1712.                         pgti->fChanged = TRUE;
  1713.                         SwitchToUpdMode( pgti->hDlg );
  1714.                     }
  1715.                     break;
  1716.                }
  1717.             }
  1718.             break;
  1719.         case IDC_DOC_TYPE:
  1720.         case IDC_DOC_EXTS:
  1721.         case IDC_DOC_DESC:
  1722.         case IDC_DOC_CMND:
  1723.             switch (nCmd)
  1724.             {
  1725.                 case EN_CHANGE:
  1726.                     if (!pgti->fInternalChange)
  1727.                     {
  1728.                         pgti->fChanged = TRUE;
  1729.                         SwitchToUpdMode( pgti->hDlg );
  1730.                     }
  1731.                     break;
  1732.                 case EN_SETFOCUS:
  1733.                     if ( pgti->mode == ADDING)
  1734.                     {
  1735.                         SET_DEF_BORDER( pgti->hDlg, IDC_ASSOC_UPD );
  1736.                         break; 
  1737.                     }
  1738.             }
  1739.             break;
  1740. #endif //0
  1741.     }
  1742.     return FALSE;
  1743. }
  1744. void AssocApply(HWND hDlg)
  1745. {
  1746.     // Delete the associations removed by the user.
  1747.     if( assocDelList )
  1748.     {
  1749.         int count = DPA_GetPtrCount( assocDelList );
  1750.         
  1751.         for(int i=0;i<count;i++)
  1752.         {
  1753.             CAssoc * pAssoc = (CAssoc *)DPA_FastGetPtr( assocDelList, i );
  1754.             if(pAssoc) 
  1755.             {
  1756.                 pAssoc->Delete();
  1757.                 delete pAssoc;
  1758.             }
  1759.         }
  1760.         DPA_Destroy( assocDelList );
  1761.         assocDelList = NULL;
  1762.     }
  1763.     // Save the currently changed associations.
  1764.     if( assocList )
  1765.     {
  1766.         int count = DPA_GetPtrCount( assocList );
  1767.         
  1768.         for(int i=0;i<count;i++)
  1769.         {
  1770.             CAssoc * pAssoc = (CAssoc *)DPA_FastGetPtr( assocList, i );
  1771.             if(pAssoc) 
  1772.             {  
  1773.                 pAssoc->Save();
  1774.             }
  1775.         }
  1776.     }
  1777. }
  1778. /****************************************************************************
  1779.  *
  1780.  * AssocDlgProc
  1781.  *
  1782.  *
  1783.  ***************************************************************************/
  1784.  
  1785. BOOL CALLBACK AssocDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1786. {
  1787.     // get our tab info structure
  1788.     LPASSOCTABINFO pgti;
  1789.     if (uMsg == WM_INITDIALOG)
  1790.     {
  1791.         // Set Limits for edit fields
  1792.         SetEditLimits( hDlg );
  1793.   
  1794.         // Allocate memory for a structure which will hold all the info
  1795.         // gathered from this page
  1796.         //
  1797.         LPASSOCTABINFO pgti = (LPASSOCTABINFO)LocalAlloc(LPTR, sizeof(ASSOCINFO));
  1798.         if (!pgti)
  1799.         {
  1800.             EndDialog(hDlg, 0);
  1801.             return FALSE;
  1802.         }
  1803.         pgti->hDlg = hDlg;
  1804.         pgti->mode = NORMAL;
  1805.         pgti->fInternalChange = FALSE;
  1806.         SetWindowLong(hDlg, DWL_USER, (LPARAM)pgti);
  1807.         
  1808.         // Create an association array from registry
  1809.         LoadAssociations();
  1810.         LoadMimeTypes();
  1811.         // Initailize dialog 
  1812.         if( InitAssocDialog(hDlg) ) 
  1813.         {
  1814.             HandleSelChange(pgti);
  1815.             return TRUE;
  1816.         }
  1817.         else
  1818.         {
  1819.             TCHAR szTitle[MAX_PATH];
  1820.             MLLoadString(IDS_ERROR_REGISTRY_TITLE, szTitle, sizeof(szTitle));
  1821.             MessageBox( GetParent(hDlg), TEXT("Cannot read associations from registry."), szTitle, MB_OK ); 
  1822.             return FALSE;
  1823.         }
  1824.     }
  1825.     else
  1826.         pgti = (LPASSOCTABINFO)GetWindowLong(hDlg, DWL_USER);
  1827.     if (!pgti)
  1828.         return FALSE;
  1829.     switch (uMsg)
  1830.     {
  1831.         case WM_NOTIFY:
  1832.         {
  1833.             NMHDR *lpnm = (NMHDR *) lParam;
  1834.             switch (lpnm->code)
  1835.             {
  1836.                 case PSN_QUERYCANCEL:
  1837.                 case PSN_KILLACTIVE:
  1838.                 case PSN_RESET:
  1839.                     SetWindowLong( hDlg, DWL_MSGRESULT, FALSE );
  1840.                     return TRUE;
  1841.                 case PSN_APPLY:
  1842.                     AssocApply(hDlg);
  1843.                     break;
  1844.             }
  1845.             break;
  1846.         }
  1847.         case WM_COMMAND:
  1848.             AssocOnCommand(pgti, LOWORD(wParam), HIWORD(wParam));
  1849.             break;
  1850.         case WM_HELP:           // F1
  1851.             //ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  1852.             //            HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1853.             break;
  1854.         case WM_CONTEXTMENU:    // right mouse click
  1855.             //ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  1856.             //            HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1857.             break;
  1858.         case WM_DESTROY:
  1859. #if 0
  1860.             RemoveDefaultDialogFont(hDlg);
  1861. #endif
  1862.             if (pgti)
  1863.                 LocalFree(pgti);
  1864.             // Remove Associated data items for the listbos items.
  1865.             ListBoxResetContents( GetDlgItem( hDlg, IDC_DOC_LIST ) );
  1866.   
  1867.             // Delete registry information
  1868.             FreeAssociations();
  1869.             FreeMimeTypes();
  1870.             SetWindowLong(hDlg, DWL_USER, (LONG)NULL);  // make sure we don't re-enter
  1871.             break;
  1872.     }
  1873.     return FALSE;
  1874. }
  1875. BOOL AssocEnter( HWND hDlg )
  1876. {
  1877.     LPASSOCTABINFO pgti = ((LPENTERASSOC)GetWindowLong(hDlg, DWL_USER))->pgti;
  1878.     BOOL bFound = FALSE;
  1879.     TCHAR szTemp [1024];
  1880.     TCHAR szTitle [80];
  1881.     CAssoc *ptr = NULL;
  1882.     TCHAR *str;
  1883.     int    index, len;
  1884.     HDPA   hdpaExts = NULL;
  1885.     HWND exts = GetDlgItem( hDlg, IDC_DOC_EXTS );
  1886.     HWND desc = GetDlgItem( hDlg, IDC_DOC_DESC );
  1887.     HWND mime = GetDlgItem( hDlg, IDC_DOC_MIME );
  1888.     HWND cmnd = GetDlgItem( hDlg, IDC_DOC_CMND );
  1889.     MLLoadString(IDS_ERROR_REGISTRY_TITLE, szTitle, sizeof(szTitle));
  1890.     // Get the pointer to existing associations.
  1891.     if(GetWindowLong(hDlg, DWL_USER))
  1892.     {
  1893.         TCHAR *pszAssoc = ((LPENTERASSOC)GetWindowLong(hDlg, DWL_USER))->pszAssoc;
  1894. if(pszAssoc && *pszAssoc)
  1895.     if( (index = FindIndex( pszAssoc ) ) != -1 )
  1896.         ptr = (CAssoc *)DPA_FastGetPtr( assocList, index );
  1897.     }
  1898.     //Check for Description
  1899.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_DESC), WM_GETTEXTLENGTH, 0, 0 );
  1900.     if( len > 0 )
  1901.     {
  1902.         str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1903.         SendMessage(GetDlgItem(hDlg, IDC_DOC_DESC), WM_GETTEXT, len+1, (LPARAM)str );
  1904.         ChopSpaces( str );
  1905.         if( *str == TEXT('') )
  1906.         {    
  1907.             LocalFree(str);
  1908.             MLLoadString(IDS_ERROR_MISSING_DESC, szTemp, sizeof(szTemp));
  1909.             MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1910.             SetFocus( GetDlgItem(hDlg, IDC_DOC_DESC) );
  1911.             return FALSE;
  1912.         }
  1913.         int assocCount = DPA_GetPtrCount( assocList );
  1914.         for( int i= 0; i<assocCount; i++ )
  1915.         {
  1916.             CAssoc * pAssoc ;
  1917.             if((pAssoc= (CAssoc *)DPA_FastGetPtr( assocList, i )) == ptr ) continue;
  1918.             
  1919.             if( StrCmpI( str, pAssoc->m_cmnd ) == NULL )
  1920.             {
  1921.                 LocalFree(str);
  1922.                 MLLoadString(IDS_ERROR_DESC_ALREADY_EXISTS, szTemp, sizeof(szTemp));
  1923.                 MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1924.                 SetFocus( GetDlgItem(hDlg, IDC_DOC_DESC) );
  1925.                 return FALSE;
  1926.             }
  1927.         }
  1928.         LocalFree(str);
  1929.     }
  1930.     else
  1931.     {
  1932.         MLLoadString(IDS_ERROR_MISSING_DESC, szTemp, sizeof(szTemp));
  1933.         MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1934.         SetFocus( GetDlgItem(hDlg, IDC_DOC_DESC) );
  1935.         return FALSE;
  1936.     }
  1937.     //Check for MIME
  1938.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_MIME), WM_GETTEXTLENGTH, 0, 0 );
  1939.     if( len > 0 )
  1940.     {
  1941.         str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1942.         SendMessage(GetDlgItem(hDlg, IDC_DOC_MIME), WM_GETTEXT, len+1, (LPARAM)str );
  1943.         ChopSpaces( str );
  1944.         if( *str != TEXT('') )
  1945.         {
  1946.             if( !StrChr( str, TEXT('/') ) )
  1947.             {
  1948.                 LocalFree(str);
  1949.                 MLLoadString(IDS_ERROR_INVALID_MIME, szTemp, sizeof(szTemp));
  1950.                 MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1951.                 SetFocus( GetDlgItem(hDlg, IDC_DOC_MIME) );
  1952.                 return FALSE;
  1953.             }
  1954.         }
  1955.         LocalFree(str);
  1956.     }
  1957.     
  1958.     //Check for command line
  1959.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_CMND), WM_GETTEXTLENGTH, 0, 0 );
  1960.     if( len > 0 )
  1961.     {
  1962.         str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1963.         SendMessage(GetDlgItem(hDlg, IDC_DOC_CMND), WM_GETTEXT, len+1, (LPARAM)str );
  1964.         ChopSpaces( str );
  1965.         if( *str == TEXT('') )
  1966.         {
  1967.             LocalFree(str);
  1968.             MLLoadString(IDS_ERROR_MISSING_CMND, szTemp, sizeof(szTemp));
  1969.             MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1970.             SetFocus( GetDlgItem(hDlg, IDC_DOC_CMND) );
  1971.             return FALSE;
  1972.         }    
  1973.         LocalFree(str);
  1974.     }
  1975.     else
  1976.     {
  1977.         MLLoadString(IDS_ERROR_MISSING_CMND, szTemp, sizeof(szTemp));
  1978.         MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1979.         SetFocus( GetDlgItem(hDlg, IDC_DOC_CMND) );
  1980.         return FALSE;
  1981.     }
  1982.     // Check for extensions.
  1983.     // User entered may already have associations in the
  1984.     // registry.
  1985.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_EXTS), WM_GETTEXTLENGTH, 0, 0 );
  1986.     str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  1987.     SendMessage(GetDlgItem(hDlg, IDC_DOC_EXTS), WM_GETTEXT, len+1, (LPARAM)str );
  1988.     int error;
  1989.     if(!(hdpaExts = CreateDPAForExts(EatSpaces(str), &error, ptr)))
  1990.     {
  1991.         LocalFree( str );
  1992.         MLLoadString(error, szTemp, sizeof(szTemp));
  1993.         MessageBox(GetParent(hDlg), szTemp, szTitle, MB_OK);
  1994.         SetFocus( GetDlgItem(hDlg, IDC_DOC_EXTS) );
  1995.         return FALSE;
  1996.     }
  1997.     LocalFree( str );
  1998.   
  1999.     // Check and Add CAssoc if we are inserting a new entry.
  2000.     if(!((LPENTERASSOC)GetWindowLong(hDlg, DWL_USER))->pszAssoc)
  2001.     {
  2002.          LPTSTR firstExt = (LPTSTR)DPA_FastGetPtr( hdpaExts, 0 );
  2003.          int len = lstrlen( firstExt ) + lstrlen(g_szDocClass) + 1;
  2004.          str = (TCHAR *)LocalAlloc( LPTR, len*sizeof(TCHAR) );
  2005.          StrCpy( str, firstExt+1   );
  2006.          StrCat( str, g_szDocClass );
  2007.          ptr = new CAssoc( str );
  2008.          ptr->m_safe = FALSE; // Since we are adding this entry.
  2009.          DPA_InsertPtr( assocList, 0x7FFF, ptr );
  2010.          LocalFree( str );
  2011.     }
  2012.     // We are not able to add or retrieve Assoc from the List
  2013.     if( ptr == NULL || ptr->m_safe == TRUE )
  2014.     {
  2015.         FreeExtensions( hdpaExts );
  2016.         return FALSE;
  2017.     }
  2018.     // Start replacing components of the Associations.
  2019.     // Replace Extensions
  2020.     if(ptr->m_exts) FreeExtensions( ptr->m_exts );
  2021.     ptr->m_exts = hdpaExts;
  2022.  
  2023.     // Replace mime type
  2024.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_MIME), WM_GETTEXTLENGTH, 0, 0 );
  2025.     str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  2026.     SendMessage(GetDlgItem(hDlg, IDC_DOC_MIME), WM_GETTEXT, len+1, (LPARAM)str );
  2027.     if( ptr->m_mime ) LocalFree( ptr->m_mime );
  2028.     ptr->m_mime = EatSpaces(str);
  2029.     // Replace Description
  2030.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_DESC), WM_GETTEXTLENGTH, 0, 0 );
  2031.     str = (TCHAR *)LocalAlloc( LPTR, (len+1)*sizeof(TCHAR) );
  2032.     SendMessage(GetDlgItem(hDlg, IDC_DOC_DESC), WM_GETTEXT, len+1, (LPARAM)str );
  2033.     if( ptr->m_desc ) LocalFree( ptr->m_desc);
  2034.     ptr->m_desc = ChopSpaces(str);
  2035.     // Replace Command Line
  2036.     len = SendMessage( GetDlgItem(hDlg, IDC_DOC_CMND), WM_GETTEXTLENGTH, 0, 0 );
  2037.     str = (TCHAR *)LocalAlloc( LPTR, (len+4)*sizeof(TCHAR) );
  2038.     SendMessage(GetDlgItem(hDlg, IDC_DOC_CMND), WM_GETTEXT, len+1, (LPARAM)str );
  2039.     if( ptr->m_cmnd ) LocalFree( ptr->m_cmnd );
  2040.     ptr->m_cmnd = ChopSpaces(str);
  2041.     if (ptr->m_stat == NEW)
  2042. if (!StrStr(ptr->m_cmnd, TEXT("%1")))
  2043.     lstrcat(ptr->m_cmnd, TEXT(" %1"));
  2044.     {
  2045.         DWORD dwCurChar;
  2046.         BOOL  bPath = FALSE;
  2047.     
  2048.         for (dwCurChar = 0; dwCurChar < lstrlen(ptr->m_cmnd); dwCurChar++)
  2049.         {
  2050.     if (ptr->m_cmnd[dwCurChar] == TEXT('/'))
  2051.             {
  2052. bPath = TRUE;
  2053.     }
  2054.     if (ptr->m_cmnd[dwCurChar] == TEXT(' '))
  2055.             {
  2056. break;
  2057.     }
  2058. }
  2059. if (bPath)  // if it's file name with no path we assume it's in the user's PATH
  2060.     {    
  2061.         CHAR szExeFile[MAX_PATH];
  2062.         TCHAR szWarning[MAX_PATH + 128];
  2063. #ifndef UNICODE
  2064.         lstrcpyn(szExeFile, ptr->m_cmnd, dwCurChar + 1);
  2065. #else
  2066.         WCHAR wszExeFile[MAX_PATH];
  2067.         lstrcpyn(wszExeFile, ptr->m_cmnd, dwCurChar + 1);
  2068.         SHUnicodeToAnsi(wszExeFile, szExeFile, ARRAYSIZE(szExeFile));
  2069. #endif
  2070.         if (access(szExeFile, X_OK) != 0)
  2071.     {
  2072. #ifndef UNICODE
  2073.             wsprintf(szWarning, TEXT("File %s is not an executable file."), szExeFile);
  2074. #else
  2075.             wsprintf(szWarning, TEXT("File %s is not an executable file."), wszExeFile);
  2076. #endif
  2077.     MessageBox( GetParent(hDlg), szWarning, TEXT("Warning"), MB_OK);
  2078.     }
  2079. }
  2080.     }
  2081.     if (Button_GetCheck(GetDlgItem(hDlg, IDC_ASSOC_EDIT)) != BST_UNCHECKED)
  2082.        ptr->m_edit &= (~FTA_OpenIsSafe );
  2083.     else
  2084.        ptr->m_edit |= FTA_OpenIsSafe;
  2085.     ptr->m_stat = UPD;
  2086.     pgti->fChanged = TRUE;
  2087.     return TRUE;
  2088. }
  2089. BOOL FAR PASCAL InitEnterAssocDialog(HWND hDlg, LPENTERASSOC penter)
  2090. {
  2091.     LPASSOCTABINFO pgti = penter->pgti;
  2092.     int index = 0;
  2093.     HWND hDlgParent = pgti->hDlg;
  2094.     TCHAR str[MAX_PATH] = TEXT("");
  2095.     if( hDlg == NULL ) return;
  2096.     HWND exts = GetDlgItem( hDlg, IDC_DOC_EXTS );
  2097.     HWND desc = GetDlgItem( hDlg, IDC_DOC_DESC );
  2098.     HWND mime = GetDlgItem( hDlg, IDC_DOC_MIME );
  2099.     HWND cmnd = GetDlgItem( hDlg, IDC_DOC_CMND );
  2100.     HWND brws = GetDlgItem( hDlg, IDC_BROWSE   );
  2101.     HWND edit = GetDlgItem( hDlg, IDC_ASSOC_EDIT );
  2102.     CAssoc * ptr = NULL;
  2103.     if(penter->pszAssoc && *(penter->pszAssoc))
  2104. if( (index = FindIndex( penter->pszAssoc ) ) != -1 )
  2105.     ptr = (CAssoc *)DPA_FastGetPtr( assocList, index );
  2106.  
  2107.     if(ptr)
  2108.     {
  2109.         SendMessage( desc, WM_SETTEXT, 0, (LPARAM)ptr->m_desc );
  2110.         SendMessage( mime, WM_SETTEXT, 0, (LPARAM)ptr->m_mime );
  2111.         SendMessage( cmnd, WM_SETTEXT, 0, (LPARAM)ptr->m_cmnd );
  2112.         // Create Extension List
  2113.         if( ptr->m_exts )
  2114.         {
  2115.             int i, count = DPA_GetPtrCount( ptr->m_exts );
  2116.             for(i=0;i<count;i++)
  2117.             {
  2118.                 StrCat( str, (LPTSTR)DPA_FastGetPtr( ptr->m_exts, i ) );
  2119.                 StrCat( str, TEXT(";") );
  2120.             }
  2121.             SendMessage( exts, WM_SETTEXT, 0, (LPARAM)str );
  2122.         }
  2123.                 
  2124.         Button_SetCheck( GetDlgItem( hDlg, IDC_ASSOC_EDIT), !(ptr->m_edit & FTA_OpenIsSafe) ); 
  2125.         EnableWindow( desc, !(ptr->m_safe) );
  2126.         EnableWindow( exts, !(ptr->m_safe) );
  2127.         EnableWindow( mime, !(ptr->m_safe) );
  2128.         EnableWindow( cmnd, !(ptr->m_safe) );
  2129.         EnableWindow( brws, !(ptr->m_safe) );
  2130.         EnableWindow( edit, !(ptr->m_safe) );
  2131.         pgti->fInternalChange = FALSE;
  2132.     }
  2133.     SetWindowLong(hDlg, DWL_USER, (LPARAM)penter);
  2134.     int mimeCount = 0;
  2135.     if( mimeList && (mimeCount = DPA_GetPtrCount(mimeList)))
  2136.     {
  2137.         for(int i=0; i< mimeCount; i++)
  2138.         {
  2139.             CMime * ptr = (CMime *)DPA_FastGetPtr( mimeList , i );
  2140.     SafeAddStringToComboBox( GetDlgItem(hDlg, IDC_DOC_MIME) , ptr->m_mime) ;
  2141.         }   
  2142.     }
  2143. }
  2144. BOOL EnterAssocOnCommand(HWND hDlg, UINT id, UINT nCmd, BOOL *pbChanged)
  2145. {
  2146.     switch (id)
  2147.     { 
  2148.         case IDC_BROWSE:
  2149.             switch (nCmd )
  2150.             {
  2151.                case BN_CLICKED:
  2152.                {
  2153.                     FindCommand( hDlg );
  2154.                     break;
  2155.                }
  2156.             }
  2157.             break;
  2158.         case IDOK:
  2159.             switch (nCmd )
  2160.             {
  2161.                 case BN_CLICKED:
  2162.                 {
  2163.     SwitchToUpdMode(GetParent(hDlg));
  2164.     if (!*pbChanged || AssocEnter(hDlg))
  2165.         return EndDialog(hDlg, 0);
  2166.     else
  2167.         break;
  2168.                 }
  2169.             }
  2170.             break;
  2171.         case IDCANCEL:
  2172.             switch (nCmd )
  2173.             {
  2174.                 case BN_CLICKED:
  2175.                 {
  2176.     return EndDialog(hDlg, 0);
  2177.                 }
  2178.             }
  2179.             break;
  2180.         case IDC_DOC_MIME:
  2181.             switch (nCmd)
  2182.             {
  2183.                 case CBN_SELCHANGE:
  2184.                 case CBN_EDITCHANGE:
  2185.     if (!*pbChanged)
  2186.     {
  2187.         *pbChanged = TRUE;
  2188.     }
  2189.                     break;
  2190.             }
  2191.             break;
  2192.         case IDC_ASSOC_EDIT:
  2193.             switch (nCmd )
  2194.             {
  2195.                case BN_CLICKED:
  2196.                {
  2197.     if (!*pbChanged)
  2198.     {
  2199.         *pbChanged = TRUE;
  2200.     }
  2201.                     break;
  2202.                }
  2203.             }
  2204.             break;
  2205.         case IDC_DOC_TYPE:
  2206.         case IDC_DOC_EXTS:
  2207.         case IDC_DOC_DESC:
  2208.         case IDC_DOC_CMND:
  2209.             switch (nCmd)
  2210.             {
  2211.                 case EN_CHANGE:
  2212.     if (!*pbChanged)
  2213.     {
  2214.         *pbChanged = TRUE;
  2215.     }
  2216.                     break;
  2217.             }
  2218.             break;
  2219.     }
  2220.     return FALSE;
  2221. }
  2222. BOOL CALLBACK EnterAssocDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2223. {
  2224.     static BOOL bChanged;
  2225.     if (uMsg == WM_INITDIALOG)
  2226.     {
  2227.         SendMessage(GetDlgItem( hDlg, IDC_DOC_MIME ), EM_LIMITTEXT, (WPARAM) MAX_PATH-1, 0);
  2228. SendMessage(GetDlgItem( hDlg, IDC_DOC_EXTS ), EM_LIMITTEXT, (WPARAM) MAX_PATH-1, 0);
  2229. SendMessage(GetDlgItem( hDlg, IDC_DOC_DESC ), EM_LIMITTEXT, (WPARAM) MAX_PATH-1, 0);
  2230. SendMessage(GetDlgItem( hDlg, IDC_DOC_CMND ), EM_LIMITTEXT, (WPARAM) MAX_PATH-1, 0);
  2231. InitEnterAssocDialog(hDlg, (LPENTERASSOC)lParam);
  2232. bChanged = FALSE;
  2233.     }
  2234.     switch (uMsg)
  2235.     {
  2236.         case WM_COMMAND:
  2237.             return EnterAssocOnCommand(hDlg, LOWORD(wParam), HIWORD(wParam), &bChanged);
  2238.             break;
  2239.     }
  2240.     return FALSE;
  2241. }