cmd.exe: Add ASSOC command.
diff --git a/programs/cmd/Cs.rc b/programs/cmd/Cs.rc index 390d875..f4a436f 100644 --- a/programs/cmd/Cs.rc +++ b/programs/cmd/Cs.rc
@@ -234,4 +234,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/De.rc b/programs/cmd/De.rc index 50a69bc..3dca9d8 100644 --- a/programs/cmd/De.rc +++ b/programs/cmd/De.rc
@@ -251,4 +251,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/En.rc b/programs/cmd/En.rc index 10891a5..e0310dd 100644 --- a/programs/cmd/En.rc +++ b/programs/cmd/En.rc
@@ -238,4 +238,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Es.rc b/programs/cmd/Es.rc index 4822007..591c217 100644 --- a/programs/cmd/Es.rc +++ b/programs/cmd/Es.rc
@@ -246,4 +246,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Fr.rc b/programs/cmd/Fr.rc index 78f206d..058cda7 100644 --- a/programs/cmd/Fr.rc +++ b/programs/cmd/Fr.rc
@@ -228,4 +228,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Ja.rc b/programs/cmd/Ja.rc index 1937480..cbad955 100644 --- a/programs/cmd/Ja.rc +++ b/programs/cmd/Ja.rc
@@ -232,4 +232,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Ko.rc b/programs/cmd/Ko.rc index fa6b83f..a62e688 100644 --- a/programs/cmd/Ko.rc +++ b/programs/cmd/Ko.rc
@@ -223,4 +223,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Makefile.in b/programs/cmd/Makefile.in index 97aedf1..3a81838 100644 --- a/programs/cmd/Makefile.in +++ b/programs/cmd/Makefile.in
@@ -4,7 +4,7 @@ VPATH = @srcdir@ MODULE = cmd.exe APPMODE = -mconsole -IMPORTS = shell32 user32 kernel32 +IMPORTS = shell32 user32 advapi32 kernel32 C_SRCS = \ batch.c \
diff --git a/programs/cmd/Nl.rc b/programs/cmd/Nl.rc index 8e8d1c4..fb43206 100644 --- a/programs/cmd/Nl.rc +++ b/programs/cmd/Nl.rc
@@ -231,4 +231,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/No.rc b/programs/cmd/No.rc index c98dd15..bf2f52e 100644 --- a/programs/cmd/No.rc +++ b/programs/cmd/No.rc
@@ -229,4 +229,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Pl.rc b/programs/cmd/Pl.rc index 5b49433..d0e7fd2 100644 --- a/programs/cmd/Pl.rc +++ b/programs/cmd/Pl.rc
@@ -225,4 +225,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Pt.rc b/programs/cmd/Pt.rc index 13a9b4c..b544db1 100644 --- a/programs/cmd/Pt.rc +++ b/programs/cmd/Pt.rc
@@ -438,4 +438,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Ru.rc b/programs/cmd/Ru.rc index 4118102..8f3bdea 100644 --- a/programs/cmd/Ru.rc +++ b/programs/cmd/Ru.rc
@@ -229,4 +229,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Si.rc b/programs/cmd/Si.rc index 7623beb..426a8d4 100644 --- a/programs/cmd/Si.rc +++ b/programs/cmd/Si.rc
@@ -230,4 +230,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
diff --git a/programs/cmd/Tr.rc b/programs/cmd/Tr.rc index bdecde3..6977407 100644 --- a/programs/cmd/Tr.rc +++ b/programs/cmd/Tr.rc
@@ -232,4 +232,5 @@ WCMD_CONFIRM, "Are you sure" WCMD_YES, "Y" WCMD_NO, "N" + WCMD_NOASSOC, "File association missing for extension %s\n" }
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); +}
diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 49307c7..fc3ce12 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h
@@ -27,6 +27,7 @@ #include <stdio.h> #include <ctype.h> +void WCMD_assoc (char *); void WCMD_batch (char *, char *, int, char *, HANDLE); void WCMD_call (char *command); void WCMD_change_tty (void); @@ -155,9 +156,10 @@ #define WCMD_SETLOCAL 37 #define WCMD_PUSHD 38 #define WCMD_POPD 39 +#define WCMD_ASSOC 40 /* Must be last in list */ -#define WCMD_EXIT 40 +#define WCMD_EXIT 41 /* Some standard messages */ extern const char nyi[]; @@ -169,6 +171,7 @@ #define WCMD_CONFIRM 1001 #define WCMD_YES 1002 #define WCMD_NO 1003 +#define WCMD_NOASSOC 1004 /* msdn specified max for Win XP */ #define MAXSTRING 8192
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index a1f426c..757cd3a 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c
@@ -26,13 +26,16 @@ #include "config.h" #include "wcmd.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(cmd); const char * const inbuilt[] = {"ATTRIB", "CALL", "CD", "CHDIR", "CLS", "COPY", "CTTY", "DATE", "DEL", "DIR", "ECHO", "ERASE", "FOR", "GOTO", "HELP", "IF", "LABEL", "MD", "MKDIR", "MOVE", "PATH", "PAUSE", "PROMPT", "REM", "REN", "RENAME", "RD", "RMDIR", "SET", "SHIFT", "TIME", "TITLE", "TYPE", "VERIFY", "VER", "VOL", - "ENDLOCAL", "SETLOCAL", "PUSHD", "POPD", "EXIT" }; + "ENDLOCAL", "SETLOCAL", "PUSHD", "POPD", "ASSOC", "EXIT" }; HINSTANCE hinst; DWORD errorlevel; @@ -441,6 +444,7 @@ * Strip leading whitespaces, and a '@' if supplied */ whichcmd = WCMD_strtrim_leading_spaces(cmd); + WINE_TRACE("Command: '%s'\n", cmd); if (whichcmd[0] == '@') whichcmd++; /* @@ -570,6 +574,9 @@ case WCMD_POPD: WCMD_popd(); break; + case WCMD_ASSOC: + WCMD_assoc(p); + break; case WCMD_EXIT: WCMD_exit (); break;