ReactOS 0.4.15-dev-8207-gd73a838
assoc.c
Go to the documentation of this file.
1/*
2 * ASSOC.C - assoc internal command.
3 *
4 *
5 * History:
6 *
7 * 14-Mar-2009 Lee C. Baker
8 * - initial implementation.
9 *
10 * 15-Mar-2009 Lee C. Baker
11 * - Don't write to (or use) HKEY_CLASSES_ROOT directly.
12 * - Externalize strings.
13 *
14 * TODO:
15 * - PrintAllAssociations could be optimized to not fetch all registry subkeys under 'Classes', just the ones that start with '.'
16 */
17
18#include "precomp.h"
19
20#ifdef INCLUDE_CMD_ASSOC
21
22static LONG
24 IN HKEY hKeyClasses,
25 IN PCTSTR pszExtension)
26{
27 LONG lRet;
28 HKEY hKey;
29 DWORD dwFileTypeLen = 0;
30 PTSTR pszFileType;
31
32 lRet = RegOpenKeyEx(hKeyClasses, pszExtension, 0, KEY_QUERY_VALUE, &hKey);
33 if (lRet != ERROR_SUCCESS)
34 {
35 if (lRet != ERROR_FILE_NOT_FOUND)
36 ErrorMessage(lRet, NULL);
37 return lRet;
38 }
39
40 /* Obtain the string length */
41 lRet = RegQueryValueEx(hKey, NULL, NULL, NULL, NULL, &dwFileTypeLen);
42
43 /* If there is no default value, don't display it */
44 if (lRet == ERROR_FILE_NOT_FOUND)
45 {
47 return lRet;
48 }
49 if (lRet != ERROR_SUCCESS)
50 {
51 ErrorMessage(lRet, NULL);
53 return lRet;
54 }
55
56 ++dwFileTypeLen;
57 pszFileType = cmd_alloc(dwFileTypeLen * sizeof(TCHAR));
58 if (!pszFileType)
59 {
60 WARN("Cannot allocate memory for pszFileType!\n");
63 }
64
65 /* Obtain the actual file type */
66 lRet = RegQueryValueEx(hKey, NULL, NULL, NULL, (LPBYTE)pszFileType, &dwFileTypeLen);
68
69 if (lRet != ERROR_SUCCESS)
70 {
71 ErrorMessage(lRet, NULL);
72 cmd_free(pszFileType);
73 return lRet;
74 }
75
76 /* If there is a default key, display the relevant information */
77 if (dwFileTypeLen != 0)
78 {
79 ConOutPrintf(_T("%s=%s\n"), pszExtension, pszFileType);
80 }
81
82 cmd_free(pszFileType);
83 return ERROR_SUCCESS;
84}
85
86static LONG
88 IN PCTSTR pszExtension)
89{
90 LONG lRet;
91 HKEY hKeyClasses;
92
93 lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0,
94 KEY_ENUMERATE_SUB_KEYS, &hKeyClasses);
95 if (lRet != ERROR_SUCCESS)
96 {
97 ErrorMessage(lRet, NULL);
98 return lRet;
99 }
100
101 lRet = PrintAssociationEx(hKeyClasses, pszExtension);
102
103 RegCloseKey(hKeyClasses);
104 return lRet;
105}
106
107static LONG
109{
110 LONG lRet;
111 HKEY hKeyClasses;
112 DWORD dwKeyCtr;
113 DWORD dwNumKeys = 0;
114 DWORD dwExtLen = 0;
115 PTSTR pszExtName;
116
117 lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0,
119 if (lRet != ERROR_SUCCESS)
120 {
121 ErrorMessage(lRet, NULL);
122 return lRet;
123 }
124
125 lRet = RegQueryInfoKey(hKeyClasses, NULL, NULL, NULL, &dwNumKeys, &dwExtLen,
126 NULL, NULL, NULL, NULL, NULL, NULL);
127 if (lRet != ERROR_SUCCESS)
128 {
129 ErrorMessage(lRet, NULL);
130 RegCloseKey(hKeyClasses);
131 return lRet;
132 }
133
134 ++dwExtLen;
135 pszExtName = cmd_alloc(dwExtLen * sizeof(TCHAR));
136 if (!pszExtName)
137 {
138 WARN("Cannot allocate memory for pszExtName!\n");
139 RegCloseKey(hKeyClasses);
141 }
142
143 for (dwKeyCtr = 0; dwKeyCtr < dwNumKeys; ++dwKeyCtr)
144 {
145 DWORD dwBufSize = dwExtLen;
146 lRet = RegEnumKeyEx(hKeyClasses, dwKeyCtr, pszExtName, &dwBufSize,
147 NULL, NULL, NULL, NULL);
148
149 if (lRet == ERROR_SUCCESS || lRet == ERROR_MORE_DATA)
150 {
151 /* Name starts with '.': this is an extension */
152 if (*pszExtName == _T('.'))
153 PrintAssociationEx(hKeyClasses, pszExtName);
154 }
155 else
156 {
157 ErrorMessage(lRet, NULL);
158 cmd_free(pszExtName);
159 RegCloseKey(hKeyClasses);
160 return lRet;
161 }
162 }
163
164 RegCloseKey(hKeyClasses);
165
166 cmd_free(pszExtName);
167 return ERROR_SUCCESS;
168}
169
170static LONG
172 IN PCTSTR pszExtension,
173 IN PCTSTR pszType)
174{
175 LONG lRet;
176 HKEY hKeyClasses, hKey;
177
178 lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0,
179 KEY_CREATE_SUB_KEY, &hKeyClasses);
180 if (lRet != ERROR_SUCCESS)
181 {
182 ErrorMessage(lRet, NULL);
183 return lRet;
184 }
185
186 lRet = RegCreateKeyEx(hKeyClasses, pszExtension, 0, NULL, REG_OPTION_NON_VOLATILE,
188 RegCloseKey(hKeyClasses);
189
190 if (lRet != ERROR_SUCCESS)
191 {
192 ErrorMessage(lRet, NULL);
193 return lRet;
194 }
195
196 lRet = RegSetValueEx(hKey, NULL, 0, REG_SZ,
197 (LPBYTE)pszType, (DWORD)(_tcslen(pszType) + 1) * sizeof(TCHAR));
199
200 if (lRet != ERROR_SUCCESS)
201 {
202 ErrorMessage(lRet, NULL);
203 return lRet;
204 }
205
206 return ERROR_SUCCESS;
207}
208
209static LONG
211 IN PCTSTR pszExtension)
212{
213 LONG lRet;
214 HKEY hKeyClasses;
215
216 lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes"), 0,
217 KEY_QUERY_VALUE, &hKeyClasses);
218 if (lRet != ERROR_SUCCESS)
219 {
220 ErrorMessage(lRet, NULL);
221 return lRet;
222 }
223
224 lRet = RegDeleteKey(hKeyClasses, pszExtension);
225 RegCloseKey(hKeyClasses);
226
227 if (lRet != ERROR_SUCCESS)
228 {
229 if (lRet != ERROR_FILE_NOT_FOUND)
230 ErrorMessage(lRet, NULL);
231 return lRet;
232 }
233
234 return ERROR_SUCCESS;
235}
236
237
239{
240 INT retval = 0;
241 PTCHAR pEqualSign;
242
243 /* Print help */
244 if (!_tcsncmp(param, _T("/?"), 2))
245 {
247 return 0;
248 }
249
250 /* Print all associations if no parameter has been specified */
251 if (!*param)
252 {
254 goto Quit;
255 }
256
257 pEqualSign = _tcschr(param, _T('='));
258 if (pEqualSign != NULL)
259 {
260 PTSTR pszFileType = pEqualSign + 1;
261
262 /* NULL-terminate at the equals sign */
263 *pEqualSign = 0;
264
265 /* If the equals sign is the last character
266 * in the string, delete the association. */
267 if (*pszFileType == 0)
268 {
269 retval = RemoveAssociation(param);
270 }
271 else
272 /* Otherwise, add the association and print it out */
273 {
274 retval = AddAssociation(param, pszFileType);
276 }
277
278 if (retval != ERROR_SUCCESS)
279 {
280 if (retval != ERROR_FILE_NOT_FOUND)
281 {
282 // FIXME: Localize
283 ConErrPrintf(_T("Error occurred while processing: %s.\n"), param);
284 }
285 // retval = 1; /* Fixup the error value */
286 }
287 }
288 else
289 {
290 /* No equals sign, print the association */
291 retval = PrintAssociation(param);
292 if (retval != ERROR_SUCCESS)
293 {
295 retval = 1; /* Fixup the error value */
296 }
297 }
298
299Quit:
300 if (BatType != CMD_TYPE)
301 {
302 if (retval != 0)
303 nErrorLevel = retval;
304 }
305 else
306 {
307 nErrorLevel = retval;
308 }
309
310 return retval;
311}
312
313#endif /* INCLUDE_CMD_ASSOC */
static VOID ErrorMessage(_In_ DWORD dwErrorCode, _In_opt_ PCWSTR pszMsg,...)
Definition: attrib.c:33
static LONG PrintAssociation(IN PCTSTR pszExtension)
Definition: assoc.c:87
static LONG AddAssociation(IN PCTSTR pszExtension, IN PCTSTR pszType)
Definition: assoc.c:171
INT CommandAssoc(LPTSTR param)
Definition: assoc.c:238
static LONG PrintAllAssociations(VOID)
Definition: assoc.c:108
static LONG RemoveAssociation(IN PCTSTR pszExtension)
Definition: assoc.c:210
static LONG PrintAssociationEx(IN HKEY hKeyClasses, IN PCTSTR pszExtension)
Definition: assoc.c:23
BATCH_TYPE BatType
Definition: batch.c:66
INT nErrorLevel
Definition: cmd.c:158
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
#define ConErrPrintf(szStr,...)
Definition: console.h:44
#define ConOutPrintf(szStr,...)
Definition: console.h:41
#define ConErrResPrintf(uID,...)
Definition: console.h:50
#define STRING_ASSOC_ERROR
Definition: resource.h:67
#define STRING_ASSOC_HELP
Definition: resource.h:83
@ CMD_TYPE
Definition: batch.h:19
#define WARN(fmt,...)
Definition: debug.h:115
#define RegCloseKey(hKey)
Definition: registry.h:49
#define cmd_free(ptr)
Definition: cmddbg.h:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLfloat param
Definition: glext.h:5796
#define _tcsncmp
Definition: tchar.h:1428
#define _tcschr
Definition: tchar.h:1406
#define REG_SZ
Definition: layer.c:22
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define KEY_SET_VALUE
Definition: nt_native.h:1017
LPCSTR PCTSTR
Definition: ntbasedef.h:488
char * PTCHAR
Definition: ntbasedef.h:476
long LONG
Definition: pedump.c:60
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
#define _T(x)
Definition: vfdio.h:22
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define RegOpenKeyEx
Definition: winreg.h:520
#define RegSetValueEx
Definition: winreg.h:533
#define RegCreateKeyEx
Definition: winreg.h:501
#define RegQueryValueEx
Definition: winreg.h:524
#define RegDeleteKey
Definition: winreg.h:502
#define RegEnumKeyEx
Definition: winreg.h:510
#define RegQueryInfoKey
Definition: winreg.h:521
char TCHAR
Definition: xmlstorage.h:189
CHAR * PTSTR
Definition: xmlstorage.h:191
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcslen
Definition: xmlstorage.h:198