cmd.exe: Add ASSOC command.
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 8418ab4..79c522c 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -1457,3 +1457,159 @@
/* Return the answer */
return (answer[0] == Ybuffer[0]);
}
+
+/*****************************************************************************
+ * WCMD_assoc
+ *
+ * Lists or sets file associations
+ */
+void WCMD_assoc (char *command) {
+
+ HKEY key;
+ DWORD accessOptions = KEY_READ;
+ char *newValue;
+ LONG rc = ERROR_SUCCESS;
+ char keyValue[MAXSTRING];
+ DWORD valueLen = MAXSTRING;
+ HKEY readKey;
+
+
+ /* See if parameter includes '=' */
+ errorlevel = 0;
+ newValue = strchr(command, '=');
+ if (newValue) accessOptions |= KEY_WRITE;
+
+ /* Open a key to HKEY_CLASSES_ROOT for enumerating */
+ if (RegOpenKeyEx(HKEY_CLASSES_ROOT, "", 0,
+ accessOptions, &key) != ERROR_SUCCESS) {
+ WINE_FIXME("Unexpected failure opening HKCR key: %d\n", GetLastError());
+ return;
+ }
+
+ /* If no paramaters then list all associations */
+ if (*command == 0x00) {
+ int index = 0;
+
+ /* Enumerate all the keys */
+ while (rc != ERROR_NO_MORE_ITEMS) {
+ char keyName[MAXSTRING];
+ DWORD nameLen;
+
+ /* Find the next value */
+ nameLen = MAXSTRING;
+ rc = RegEnumKeyEx(key, index++,
+ keyName, &nameLen,
+ NULL, NULL, NULL, NULL);
+
+ if (rc == ERROR_SUCCESS) {
+
+ /* Only interested in extension ones */
+ if (keyName[0] == '.') {
+
+ if (RegOpenKeyEx(key, keyName, 0,
+ accessOptions, &readKey) == ERROR_SUCCESS) {
+
+ rc = RegQueryValueEx(readKey, NULL, NULL, NULL,
+ (LPBYTE)keyValue, &valueLen);
+ WCMD_output_asis(keyName);
+ WCMD_output_asis("=");
+ /* If no default value found, leave line empty after '=' */
+ if (rc == ERROR_SUCCESS) {
+ WCMD_output_asis(keyValue);
+ }
+ WCMD_output_asis("\n");
+ }
+ }
+ }
+ }
+ RegCloseKey(readKey);
+
+ } else {
+
+ /* Parameter supplied - if no '=' on command line, its a query */
+ if (newValue == NULL) {
+ char *space;
+
+ /* Query terminates the parameter at the first space */
+ strcpy(keyValue, command);
+ space = strchr(keyValue, ' ');
+ if (space) *space=0x00;
+
+ if (RegOpenKeyEx(key, keyValue, 0,
+ accessOptions, &readKey) == ERROR_SUCCESS) {
+
+ rc = RegQueryValueEx(readKey, NULL, NULL, NULL,
+ (LPBYTE)keyValue, &valueLen);
+ WCMD_output_asis(command);
+ WCMD_output_asis("=");
+ /* If no default value found, leave line empty after '=' */
+ if (rc == ERROR_SUCCESS) WCMD_output_asis(keyValue);
+ WCMD_output_asis("\n");
+ RegCloseKey(readKey);
+
+ } else {
+ char msgbuffer[MAXSTRING];
+ char outbuffer[MAXSTRING];
+
+ /* Load the translated 'File association not found' */
+ LoadString (hinst, WCMD_NOASSOC, msgbuffer, sizeof(msgbuffer));
+ sprintf(outbuffer, msgbuffer, keyValue);
+ WCMD_output_asis(outbuffer);
+ errorlevel = 2;
+ }
+
+ /* Not a query - its a set or clear of a value */
+ } else {
+
+ /* Get pointer to new value */
+ *newValue = 0x00;
+ newValue++;
+
+ /* If nothing after '=' then clear value */
+ if (*newValue == 0x00) {
+
+ rc = RegDeleteKey(key, command);
+ if (rc == ERROR_SUCCESS) {
+ WINE_TRACE("HKCR Key '%s' deleted\n", command);
+
+ } else if (rc != ERROR_FILE_NOT_FOUND) {
+ WCMD_print_error();
+ errorlevel = 2;
+
+ } else {
+ char msgbuffer[MAXSTRING];
+ char outbuffer[MAXSTRING];
+
+ /* Load the translated 'File association not found' */
+ LoadString (hinst, WCMD_NOASSOC, msgbuffer, sizeof(msgbuffer));
+ sprintf(outbuffer, msgbuffer, keyValue);
+ WCMD_output_asis(outbuffer);
+ errorlevel = 2;
+ }
+
+ /* It really is a set value = contents */
+ } else {
+ rc = RegCreateKeyEx(key, command, 0, NULL, REG_OPTION_NON_VOLATILE,
+ accessOptions, NULL, &readKey, NULL);
+ if (rc == ERROR_SUCCESS) {
+ rc = RegSetValueEx(readKey, NULL, 0, REG_SZ,
+ (LPBYTE)newValue, strlen(newValue));
+ RegCloseKey(readKey);
+ }
+
+ if (rc != ERROR_SUCCESS) {
+ WCMD_print_error();
+ errorlevel = 2;
+ } else {
+ WCMD_output_asis(command);
+ WCMD_output_asis("=");
+ WCMD_output_asis(newValue);
+ WCMD_output_asis("\n");
+ }
+ }
+ }
+ }
+
+ /* Clean up */
+ RegCloseKey(key);
+}