2 * Assoc.C - assoc internal command.
7 * 14-Mar-2009 Lee C. Baker
8 * - initial implementation
10 * 15-Mar-2009 Lee C. Baker
11 * - Don't write to (or use) HKEY_CLASSES_ROOT directly
12 * - Externalize strings
15 * - PrintAllAssociations might could be optimized to not fetch all registry subkeys under 'Classes', just the ones that start with '.'
16 * - Make sure that non-administrator users can list associations, and get appropriate error messages when they don't have sufficient
17 * priveleges to perform an operation
22 #ifdef INCLUDE_CMD_ASSOC
25 PrintAssociation(LPTSTR extension
)
28 HKEY hKey
= NULL
, hInsideKey
= NULL
;
30 DWORD fileTypeLength
= 0;
31 LPTSTR fileType
= NULL
;
33 return_val
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, _T("SOFTWARE\\Classes"), 0, KEY_READ
, &hKey
);
35 if(return_val
!= ERROR_SUCCESS
)
41 return_val
= RegOpenKeyEx(hKey
, extension
, 0, KEY_READ
, &hInsideKey
);
43 if(return_val
!= ERROR_SUCCESS
)
46 RegCloseKey(hInsideKey
);
50 /* obtain string length */
51 return_val
= RegQueryValueEx(hInsideKey
, NULL
, NULL
, NULL
, NULL
, &fileTypeLength
);
53 if(return_val
== ERROR_FILE_NOT_FOUND
) /* no default value, don't display */
55 RegCloseKey(hInsideKey
);
60 if(return_val
!= ERROR_SUCCESS
)
62 RegCloseKey(hInsideKey
);
67 fileType
= cmd_alloc(fileTypeLength
* sizeof(TCHAR
));
69 /* obtain actual file type */
70 return_val
= RegQueryValueEx(hInsideKey
, NULL
, NULL
, NULL
, (LPBYTE
) fileType
, &fileTypeLength
);
72 RegCloseKey(hInsideKey
);
75 if(return_val
!= ERROR_SUCCESS
)
81 if(fileTypeLength
!= 0) /* if there is a default key, display relevant information */
83 ConOutPrintf(_T("%s=%s\r\n"), extension
, fileType
);
93 PrintAllAssociations()
100 LPTSTR extName
= NULL
;
103 return_val
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, _T("SOFTWARE\\Classes"), 0, KEY_READ
, &hKey
);
105 if(return_val
!= ERROR_SUCCESS
)
111 return_val
= RegQueryInfoKey(hKey
, NULL
, NULL
, NULL
, &numKeys
, &extLength
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
113 if(return_val
!= ERROR_SUCCESS
)
119 extName
= cmd_alloc(extLength
* sizeof(TCHAR
));
121 for(keyCtr
= 0; keyCtr
< numKeys
; keyCtr
++)
123 DWORD buffer_size
= extLength
;
124 return_val
= RegEnumKeyEx(hKey
, keyCtr
, extName
, &buffer_size
, NULL
, NULL
, NULL
, NULL
);
126 if(return_val
== ERROR_SUCCESS
|| return_val
== ERROR_MORE_DATA
)
128 if(*extName
== _T('.'))
129 PrintAssociation(extName
);
148 AddAssociation(LPTSTR extension
, LPTSTR type
)
151 HKEY hKey
= NULL
, insideKey
= NULL
;
153 return_val
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, _T("SOFTWARE\\Classes"), 0, KEY_ALL_ACCESS
, &hKey
);
155 if(return_val
!= ERROR_SUCCESS
)
158 return_val
= RegCreateKeyEx(hKey
, extension
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &insideKey
, NULL
);
160 if(return_val
!= ERROR_SUCCESS
)
166 return_val
= RegSetValueEx(insideKey
, NULL
, 0, REG_SZ
, (LPBYTE
)type
, (_tcslen(type
) + 1) * sizeof(TCHAR
));
168 if(return_val
!= ERROR_SUCCESS
)
170 RegCloseKey(insideKey
);
175 RegCloseKey(insideKey
);
182 RemoveAssociation(LPTSTR extension
)
187 return_val
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, _T("SOFTWARE\\Classes"), 0, KEY_ALL_ACCESS
, &hKey
);
189 if(return_val
!= ERROR_SUCCESS
)
192 return_val
= RegDeleteKey(hKey
, extension
);
194 if(return_val
!= ERROR_SUCCESS
)
206 INT
CommandAssoc (LPTSTR param
)
210 if (!_tcsncmp (param
, _T("/?"), 2))
212 ConOutResPaging(TRUE
,STRING_ASSOC_HELP
);
218 if(_tcslen(param
) == 0)
219 PrintAllAssociations();
222 LPTSTR lpEqualSign
= _tcschr(param
, _T('='));
223 if(lpEqualSign
!= NULL
)
225 LPTSTR fileType
= lpEqualSign
+ 1;
226 LPTSTR extension
= cmd_alloc((lpEqualSign
- param
+ 1) * sizeof(TCHAR
));
228 _tcsncpy(extension
, param
, lpEqualSign
- param
);
229 extension
[lpEqualSign
- param
] = (TCHAR
)0;
231 if(_tcslen(fileType
) == 0)
232 /* if the equal sign is the last character
233 in the string, then delete the key */
235 RemoveAssociation(extension
);
238 /* otherwise, add the key and print out the association*/
240 AddAssociation( extension
, fileType
);
241 PrintAssociation(extension
);
248 /* no equal sign, print all associations */
249 INT retval
= PrintAssociation(param
);
251 if(retval
== 0) /* if nothing printed out */
252 ConOutResPrintf(STRING_ASSOC_ERROR
, param
);
259 #endif /* INCLUDE_CMD_ASSOC */