From c37ff9ea326ab64073066dc12fe55722a4b1aced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Wed, 29 Jun 2016 00:38:51 +0000 Subject: [PATCH] [SUBST] - Update the resource program description. - Convert to full UNICODE. - Use Win32 functions where possible. - Factor-out the usage of QueryDosDevice into a QuerySubstedDrive function, that returns error codes according to whether the specified drive is a mapped (substed) drive, or is just an existing drive that is not a mapping, or if the drive does not exist. This allows us to detect attempts to use a drive letter that is not a mapped drive, to define a new mapping, and if so we reject such attempt. This fixes CORE-10681 #resolve #comment Fixed with another patch according to my last remark. svn path=/trunk/; revision=71695 --- reactos/base/system/subst/lang/bg-BG.rc | 1 + reactos/base/system/subst/lang/de-DE.rc | 1 + reactos/base/system/subst/lang/en-US.rc | 1 + reactos/base/system/subst/lang/es-ES.rc | 1 + reactos/base/system/subst/lang/fr-FR.rc | 1 + reactos/base/system/subst/lang/it-IT.rc | 1 + reactos/base/system/subst/lang/pl-PL.rc | 1 + reactos/base/system/subst/lang/ro-RO.rc | 1 + reactos/base/system/subst/lang/ru-RU.rc | 1 + reactos/base/system/subst/lang/sq-AL.rc | 1 + reactos/base/system/subst/lang/tr-TR.rc | 1 + reactos/base/system/subst/lang/uk-UA.rc | 1 + reactos/base/system/subst/lang/zh-CN.rc | 1 + reactos/base/system/subst/lang/zh-TW.rc | 1 + reactos/base/system/subst/resource.h | 3 +- reactos/base/system/subst/subst.c | 413 ++++++++++++++---------- reactos/base/system/subst/subst.rc | 6 +- 17 files changed, 270 insertions(+), 166 deletions(-) diff --git a/reactos/base/system/subst/lang/bg-BG.rc b/reactos/base/system/subst/lang/bg-BG.rc index a458b296b16..a6994082a67 100644 --- a/reactos/base/system/subst/lang/bg-BG.rc +++ b/reactos/base/system/subst/lang/bg-BG.rc @@ -6,6 +6,7 @@ BEGIN IDS_INVALID_PARAMETER "Неправилен брой ключове - %s\n" IDS_INVALID_PARAMETER2 "Недопустим ключ - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Устройството вече е подложено на SUBST\n" IDS_FAILED_WITH_ERRORCODE "Грешка номер: 0x%x: %s\n" IDS_USAGE "Обвързва път с име на устройство (дял).\n\n\ diff --git a/reactos/base/system/subst/lang/de-DE.rc b/reactos/base/system/subst/lang/de-DE.rc index 3c37008d378..98e545d6ba7 100644 --- a/reactos/base/system/subst/lang/de-DE.rc +++ b/reactos/base/system/subst/lang/de-DE.rc @@ -6,6 +6,7 @@ BEGIN IDS_INVALID_PARAMETER "Falsche Anzahl an Parametern - %s\n" IDS_INVALID_PARAMETER2 "Falscher Parameter - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "SUBST wurde hier schon ausgeführt.\n" IDS_FAILED_WITH_ERRORCODE "Fehlgeschlagen - Code 0x%x: %s\n" IDS_USAGE "Weist einem Pfad einen Laufwerksbuchstaben zu.n\n\ diff --git a/reactos/base/system/subst/lang/en-US.rc b/reactos/base/system/subst/lang/en-US.rc index 94d7faa07cd..667d4c03cac 100644 --- a/reactos/base/system/subst/lang/en-US.rc +++ b/reactos/base/system/subst/lang/en-US.rc @@ -6,6 +6,7 @@ BEGIN IDS_INVALID_PARAMETER "Incorrect number of parameters - %s\n" IDS_INVALID_PARAMETER2 "Invalid parameter - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Drive already SUBSTed\n" IDS_FAILED_WITH_ERRORCODE "Failed with error code 0x%x: %s\n" IDS_USAGE "Associates a path with a drive letter.\n\n\ diff --git a/reactos/base/system/subst/lang/es-ES.rc b/reactos/base/system/subst/lang/es-ES.rc index 004ff4e698e..93d668f6179 100644 --- a/reactos/base/system/subst/lang/es-ES.rc +++ b/reactos/base/system/subst/lang/es-ES.rc @@ -6,6 +6,7 @@ BEGIN IDS_INVALID_PARAMETER "Cantidad de parámetros incorrecta - %s\n" IDS_INVALID_PARAMETER2 "Parámetro incorrecto - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Unidad ya sustituida\n" IDS_FAILED_WITH_ERRORCODE "Falla con código de error 0x%x: %s\n" IDS_USAGE "Asocia una ruta con una letra de unidad.\n\n\ diff --git a/reactos/base/system/subst/lang/fr-FR.rc b/reactos/base/system/subst/lang/fr-FR.rc index 53b2c3f32ae..ebb9bd1757a 100644 --- a/reactos/base/system/subst/lang/fr-FR.rc +++ b/reactos/base/system/subst/lang/fr-FR.rc @@ -6,6 +6,7 @@ BEGIN IDS_INVALID_PARAMETER "Nombre incorrect de paramètres - %s\n" IDS_INVALID_PARAMETER2 "Paramètre incorrect - %s\n" IDS_PATH_NOT_FOUND "Chemin d'accès introuvable - %s\n" + IDS_ACCESS_DENIED "Accès refusé - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Disque déjà substitué\n" IDS_FAILED_WITH_ERRORCODE "Échoue avec le code d'erreur 0x%x : %s\n" IDS_USAGE "Associe un chemin avec une lettre de lecteur.\n\n\ diff --git a/reactos/base/system/subst/lang/it-IT.rc b/reactos/base/system/subst/lang/it-IT.rc index 20d7e87dada..9f5c969ef6f 100644 --- a/reactos/base/system/subst/lang/it-IT.rc +++ b/reactos/base/system/subst/lang/it-IT.rc @@ -6,6 +6,7 @@ BEGIN IDS_INVALID_PARAMETER "Numero di parametri errato - %s\n" IDS_INVALID_PARAMETER2 "Parametro errato - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Unità già sostituita\n" IDS_FAILED_WITH_ERRORCODE "Interruzione con codice di errore 0x%x: %s\n" IDS_USAGE "Associa un percorso ad una lettera di unità.\n\n\ diff --git a/reactos/base/system/subst/lang/pl-PL.rc b/reactos/base/system/subst/lang/pl-PL.rc index 5b56f74d25d..18b4cc67233 100644 --- a/reactos/base/system/subst/lang/pl-PL.rc +++ b/reactos/base/system/subst/lang/pl-PL.rc @@ -14,6 +14,7 @@ BEGIN IDS_INVALID_PARAMETER "Nieprawidłowy parametr - %s\n" IDS_INVALID_PARAMETER2 "Nieprawidłowe parametry - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Na tym dysku już użyto komendy SUBST\n" IDS_FAILED_WITH_ERRORCODE "Błąd 0x%x: %s\n" IDS_USAGE "Powiązuje ścieżkę z literą napędu.\n\n\ diff --git a/reactos/base/system/subst/lang/ro-RO.rc b/reactos/base/system/subst/lang/ro-RO.rc index 11d5e73df50..1d7960cd666 100644 --- a/reactos/base/system/subst/lang/ro-RO.rc +++ b/reactos/base/system/subst/lang/ro-RO.rc @@ -8,6 +8,7 @@ BEGIN IDS_INVALID_PARAMETER "Număr eronat de parametri - %s\n" IDS_INVALID_PARAMETER2 "Parametru eronat - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Unitatea este deja SUBSTituită\n" IDS_FAILED_WITH_ERRORCODE "Operația a eșuat. Codul de eroare 0x%x: %s\n" IDS_USAGE "Substituie un director cu o unitate de stocare.\n\n\ diff --git a/reactos/base/system/subst/lang/ru-RU.rc b/reactos/base/system/subst/lang/ru-RU.rc index 07ace0edf7f..9a4d33828c1 100644 --- a/reactos/base/system/subst/lang/ru-RU.rc +++ b/reactos/base/system/subst/lang/ru-RU.rc @@ -8,6 +8,7 @@ BEGIN IDS_INVALID_PARAMETER "Неверное число параметров - %s\n" IDS_INVALID_PARAMETER2 "Неверный параметр - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Диск уже сопоставлен\n" IDS_FAILED_WITH_ERRORCODE "Сбой с кодом ошибки 0x%x: %s\n" IDS_USAGE "Сопоставление имени диска указанному пути.\n\n\ diff --git a/reactos/base/system/subst/lang/sq-AL.rc b/reactos/base/system/subst/lang/sq-AL.rc index b7fbd0f69f6..1ab4d81b8ee 100644 --- a/reactos/base/system/subst/lang/sq-AL.rc +++ b/reactos/base/system/subst/lang/sq-AL.rc @@ -10,6 +10,7 @@ BEGIN IDS_INVALID_PARAMETER "Numri i parametrave jo i sakte - %s\n" IDS_INVALID_PARAMETER2 "Parameter i gabuar - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Drive tashme i SUBSTed\n" IDS_FAILED_WITH_ERRORCODE "Deshtoj me error kode 0x%x: %s\n" IDS_USAGE "Perputh rrugen e driverit me germën.\n\n\ diff --git a/reactos/base/system/subst/lang/tr-TR.rc b/reactos/base/system/subst/lang/tr-TR.rc index f7697ba663a..503e9d92c26 100644 --- a/reactos/base/system/subst/lang/tr-TR.rc +++ b/reactos/base/system/subst/lang/tr-TR.rc @@ -8,6 +8,7 @@ BEGIN IDS_INVALID_PARAMETER "Değişken sayısı yanlış - %s\n" IDS_INVALID_PARAMETER2 "Geçersiz değişken - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "Sürücü önceden SUBST edilmiş.\n" IDS_FAILED_WITH_ERRORCODE "Yanlışlık kodu ile başarısız oldu 0x%x: %s\n" IDS_USAGE "Bir sürücü harfiyle bir yolu ilişkilendirir.\n\n\ diff --git a/reactos/base/system/subst/lang/uk-UA.rc b/reactos/base/system/subst/lang/uk-UA.rc index 58fe090df3f..356ceecb2d0 100644 --- a/reactos/base/system/subst/lang/uk-UA.rc +++ b/reactos/base/system/subst/lang/uk-UA.rc @@ -8,6 +8,7 @@ BEGIN IDS_INVALID_PARAMETER "Невірна кількість параметрів - %s\n" IDS_INVALID_PARAMETER2 "Невірний параметр - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "До диску вже застосовано SUBST\n" IDS_FAILED_WITH_ERRORCODE "Невдача з кодом помилки 0x%x: %s\n" IDS_USAGE "Асоціює шлях з буквою диску.\n\n\ diff --git a/reactos/base/system/subst/lang/zh-CN.rc b/reactos/base/system/subst/lang/zh-CN.rc index 9ba7be706aa..b758f6a15e6 100644 --- a/reactos/base/system/subst/lang/zh-CN.rc +++ b/reactos/base/system/subst/lang/zh-CN.rc @@ -8,6 +8,7 @@ BEGIN IDS_INVALID_PARAMETER "参数个数不正确 - %s\n" IDS_INVALID_PARAMETER2 "无效参数 - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "驱动器已经运行过 SUBST\n" IDS_FAILED_WITH_ERRORCODE "操作失败!错误码 0x%x:%s\n" IDS_USAGE "将一个路径用驱动器号关联。\n\n\ diff --git a/reactos/base/system/subst/lang/zh-TW.rc b/reactos/base/system/subst/lang/zh-TW.rc index c90a4e1383f..145ae32b8aa 100644 --- a/reactos/base/system/subst/lang/zh-TW.rc +++ b/reactos/base/system/subst/lang/zh-TW.rc @@ -8,6 +8,7 @@ BEGIN IDS_INVALID_PARAMETER "參數個數不正確 - %s\n" IDS_INVALID_PARAMETER2 "無效參數 - %s\n" IDS_PATH_NOT_FOUND "Path not found - %s\n" + IDS_ACCESS_DENIED "Access denied - %s\n" IDS_DRIVE_ALREADY_SUBSTED "驅動器已經運行過 SUBST\n" IDS_FAILED_WITH_ERRORCODE "操作失敗!錯誤碼 0x%x:%s\n" IDS_USAGE "將一個路徑用驅動器號關聯。\n\n\ diff --git a/reactos/base/system/subst/resource.h b/reactos/base/system/subst/resource.h index ec56e1da6b1..6abc07d3fc6 100644 --- a/reactos/base/system/subst/resource.h +++ b/reactos/base/system/subst/resource.h @@ -9,4 +9,5 @@ #define IDS_INVALID_PARAMETER 1004 #define IDS_INVALID_PARAMETER2 1005 #define IDS_PATH_NOT_FOUND 1006 -#define IDS_DRIVE_ALREADY_SUBSTED 1007 +#define IDS_ACCESS_DENIED 1007 +#define IDS_DRIVE_ALREADY_SUBSTED 1008 diff --git a/reactos/base/system/subst/subst.c b/reactos/base/system/subst/subst.c index f54e70dbf2d..bbbd8d970d7 100644 --- a/reactos/base/system/subst/subst.c +++ b/reactos/base/system/subst/subst.c @@ -1,212 +1,254 @@ -/* PROJECT: ReactOS Kernel +/* + * PROJECT: ReactOS Subst Command * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/subst/subst.c - * PURPOSE: Associates a path with a drive letter + * PURPOSE: Maps a path with a drive letter * PROGRAMMERS: Sam Arun Raj + * Peter Hater + * Hermes Belusca-Maito */ /* INCLUDES *****************************************************************/ -#include -#include -#include +#include #define WIN32_NO_STATUS #include #include #include -#define NDEBUG -#include - #include "resource.h" /* FUNCTIONS ****************************************************************/ -VOID PrintError(DWORD ErrCode) +VOID PrintError(IN DWORD ErrCode) { - TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0}; - TCHAR *buffer = (TCHAR*) calloc(2048, - sizeof(TCHAR)); - TCHAR *msg = NULL; + WCHAR szFmtString[RC_STRING_MAX_SIZE] = {0}; + PWSTR buffer, msg = NULL; - if (buffer) + buffer = (PWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2048 * sizeof(WCHAR)); + if (!buffer) + return; + + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + ErrCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (PWSTR)&msg, + 0, + NULL); + if (msg) { - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - ErrCode, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (TCHAR*)&msg, - 0, - NULL); - LoadString(GetModuleHandle(NULL), - IDS_FAILED_WITH_ERRORCODE, - szFmtString, - ARRAYSIZE(szFmtString)); - _sntprintf(buffer, + LoadStringW(GetModuleHandleW(NULL), + IDS_FAILED_WITH_ERRORCODE, + szFmtString, + ARRAYSIZE(szFmtString)); + _snwprintf(buffer, 2048, szFmtString, ErrCode, msg); - _tprintf(_T("%s"), - buffer); - if (msg) - LocalFree(msg); - free(buffer); + wprintf(L"%s", buffer); + + LocalFree(msg); } + + HeapFree(GetProcessHeap(), 0, buffer); } VOID DisplaySubstUsage(VOID) { - TCHAR szHelp[RC_STRING_MAX_SIZE] = {0}; + WCHAR szHelp[RC_STRING_MAX_SIZE] = {0}; - LoadString(GetModuleHandle(NULL), + LoadStringW(GetModuleHandleW(NULL), IDS_USAGE, szHelp, ARRAYSIZE(szHelp)); - _tprintf(_T("%s"), szHelp); + wprintf(L"%s", szHelp); } -BOOLEAN IsSubstedDrive(TCHAR DriveLetter) +ULONG QuerySubstedDrive(IN WCHAR DriveLetter, + IN OUT PWSTR* TargetPath OPTIONAL, + IN OUT PULONG Size) { - BOOLEAN Result = FALSE; - TCHAR Drive[3] = _T("A:"); - LPTSTR lpTargetPath = NULL; - DWORD CharCount, dwSize; + ULONG Result = ERROR_INVALID_DRIVE; + WCHAR Drive[] = L"A:"; + DWORD dwSize, CharCount = 0; + PWSTR lpTargetPath = NULL, tmp; Drive[0] = DriveLetter; - dwSize = MAX_PATH; - lpTargetPath = (LPTSTR)malloc(sizeof(TCHAR) * dwSize); - if (!lpTargetPath) - return FALSE; - - CharCount = QueryDosDevice(Drive, - lpTargetPath, - dwSize); - while (!CharCount && - GetLastError() == ERROR_INSUFFICIENT_BUFFER) + /* Check whether the user has given a pointer to a target path buffer */ + if (!TargetPath) { - lpTargetPath = (LPTSTR)realloc(lpTargetPath, sizeof(TCHAR) * dwSize); - if (lpTargetPath) + /* No, therefore use a local buffer */ + dwSize = MAX_PATH; + lpTargetPath = (PWSTR)HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR)); + if (!lpTargetPath) + return ERROR_NOT_ENOUGH_MEMORY; + } + else + { + /* Just use the user-given pointer to a buffer; Size should point to a valid ULONG */ + if (!Size) + return ERROR_INVALID_PARAMETER; + + lpTargetPath = *TargetPath; + dwSize = *Size; + } + +Retry: + /* Try querying DOS device information */ + CharCount = QueryDosDeviceW(Drive, lpTargetPath, dwSize); + if (!CharCount) + Result = GetLastError(); + + if (!CharCount && (Result == ERROR_INSUFFICIENT_BUFFER)) + { + /* Reallocate the buffer with double size */ + dwSize *= 2; + tmp = (PWSTR)HeapReAlloc(GetProcessHeap(), 0, lpTargetPath, dwSize * sizeof(WCHAR)); + if (!tmp) { - CharCount = QueryDosDevice(Drive, - lpTargetPath, - dwSize); + /* Memory problem, bail out */ + CharCount = 0; + Result = ERROR_NOT_ENOUGH_MEMORY; + } + else + { + /* Retry again */ + lpTargetPath = tmp; + goto Retry; } } if (CharCount) { - Result = _tcsncmp(lpTargetPath, _T("\\??\\"), 4) == 0 && - ( (lpTargetPath[4] >= _T('A') && - lpTargetPath[4] <= _T('Z')) || - (lpTargetPath[4] >= _T('a') && - lpTargetPath[4] <= _T('z')) ); + if ( wcsncmp(lpTargetPath, L"\\??\\", 4) == 0 && + ( (lpTargetPath[4] >= L'A' && lpTargetPath[4] <= L'Z') || + (lpTargetPath[4] >= L'a' && lpTargetPath[4] <= L'z') ) ) + { + /* The drive exists and is SUBSTed */ + Result = ERROR_IS_SUBSTED; + } +#if 0 + else + { + /* The drive exists but is not SUBSTed */ + Result = ERROR_INVALID_DRIVE; + } +#endif } - free(lpTargetPath); + if (!TargetPath) + { + /* Free the local buffer */ + HeapFree(GetProcessHeap(), 0, lpTargetPath); + } + else + { + /* Update the user-given pointers */ + *TargetPath = lpTargetPath; + *Size = dwSize; + } return Result; } VOID DumpSubstedDrives(VOID) { - TCHAR Drive[3] = _T("A:"); - LPTSTR lpTargetPath = NULL; - DWORD CharCount, dwSize; - INT i = 0; + WCHAR DriveLetter; + PWSTR lpTargetPath = NULL; + DWORD dwSize; + UCHAR i = 0; dwSize = MAX_PATH; - lpTargetPath = (LPTSTR)malloc(sizeof(TCHAR) * dwSize); + lpTargetPath = (PWSTR)HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR)); if (!lpTargetPath) return; while (i < 26) { - Drive[0] = _T('A') + i; - CharCount = QueryDosDevice(Drive, - lpTargetPath, - dwSize); - while (!CharCount && - GetLastError() == ERROR_INSUFFICIENT_BUFFER) + DriveLetter = L'A' + i; + if (QuerySubstedDrive(DriveLetter, &lpTargetPath, &dwSize) == ERROR_IS_SUBSTED) { - lpTargetPath = (LPTSTR)realloc(lpTargetPath, sizeof(TCHAR) * dwSize); - if (lpTargetPath) - { - CharCount = QueryDosDevice(Drive, - lpTargetPath, - dwSize); - } - } - - if (CharCount) - { - if ( _tcsncmp(lpTargetPath, _T("\\??\\"), 4) == 0 && - ( (lpTargetPath[4] >= _T('A') && - lpTargetPath[4] <= _T('Z')) || - (lpTargetPath[4] >= _T('a') && - lpTargetPath[4] <= _T('z')) ) ) - { - _tprintf(_T("%s\\: => %s\n"), - Drive, - lpTargetPath + 4); - } + wprintf(L"%c:\\: => %s\n", DriveLetter, lpTargetPath + 4); } i++; } - free(lpTargetPath); + HeapFree(GetProcessHeap(), 0, lpTargetPath); } -INT DeleteSubst(TCHAR* Drive) +INT DeleteSubst(IN PWSTR Drive) { - BOOL Result; - TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0}; + DWORD dwResult; + WCHAR szFmtString[RC_STRING_MAX_SIZE] = {0}; - LoadString(GetModuleHandle(NULL), - IDS_INVALID_PARAMETER2, - szFmtString, - ARRAYSIZE(szFmtString)); - - if ((_tcslen(Drive) != 2) || (Drive[1] != _T(':'))) + if ((wcslen(Drive) != 2) || (Drive[1] != L':')) { - _tprintf(szFmtString, Drive); - return 1; + dwResult = ERROR_INVALID_PARAMETER; + goto Quit; } - if (!IsSubstedDrive(Drive[0])) + if (QuerySubstedDrive(Drive[0], NULL, NULL) != ERROR_IS_SUBSTED) { - _tprintf(szFmtString, Drive); - return 1; + dwResult = ERROR_INVALID_PARAMETER; + goto Quit; } - Result = DefineDosDevice(DDD_REMOVE_DEFINITION, - Drive, - NULL); - if (!Result) + if (!DefineDosDeviceW(DDD_REMOVE_DEFINITION, Drive, NULL)) + dwResult = GetLastError(); + else + dwResult = ERROR_SUCCESS; + +Quit: + switch (dwResult) { - PrintError(GetLastError()); - return 1; + case ERROR_SUCCESS: + break; + + // case ERROR_INVALID_DRIVE: + case ERROR_INVALID_PARAMETER: + { + LoadStringW(GetModuleHandleW(NULL), + IDS_INVALID_PARAMETER2, + szFmtString, + ARRAYSIZE(szFmtString)); + wprintf(szFmtString, Drive); + return 1; + } + + case ERROR_ACCESS_DENIED: + { + LoadStringW(GetModuleHandleW(NULL), + IDS_ACCESS_DENIED, + szFmtString, + ARRAYSIZE(szFmtString)); + wprintf(szFmtString, Drive); + return 1; + } + + default: + { + PrintError(GetLastError()); + return 1; + } } + return 0; } -INT AddSubst(TCHAR* Drive, TCHAR *Path) +INT AddSubst(IN PWSTR Drive, IN PWSTR Path) { - BOOL Result; - DWORD dwPathAttr; - TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0}; + DWORD dwResult, dwPathAttr; + WCHAR szFmtString[RC_STRING_MAX_SIZE] = {0}; - if ((_tcslen(Drive) != 2) || (Drive[1] != _T(':'))) + if ((wcslen(Drive) != 2) || (Drive[1] != L':')) { - LoadString(GetModuleHandle(NULL), - IDS_INVALID_PARAMETER2, - szFmtString, - ARRAYSIZE(szFmtString)); - _tprintf(szFmtString, Drive); - return 1; + dwResult = ERROR_INVALID_PARAMETER; + goto Quit; } /* @@ -215,48 +257,95 @@ INT AddSubst(TCHAR* Drive, TCHAR *Path) * the given path exists and really is a path to a directory, and if not, * just fail with an error. */ - dwPathAttr = GetFileAttributes(Path); + dwPathAttr = GetFileAttributesW(Path); if ( (dwPathAttr == INVALID_FILE_ATTRIBUTES) || !(dwPathAttr & FILE_ATTRIBUTE_DIRECTORY) ) { - LoadString(GetModuleHandle(NULL), - IDS_PATH_NOT_FOUND, - szFmtString, - ARRAYSIZE(szFmtString)); - _tprintf(szFmtString, Path); - return 1; + dwResult = ERROR_PATH_NOT_FOUND; + goto Quit; } - if (IsSubstedDrive(Drive[0])) + /* + * QuerySubstedDrive (via QueryDosDevice) returns ERROR_FILE_NOT_FOUND only + * if there is no already existing drive mapping. For all other results + * (existing drive, be it already subst'ed or not, or other errors...) + * no attempt at defining a drive mapping should be done. + */ + dwResult = QuerySubstedDrive(Drive[0], NULL, NULL); + if (dwResult != ERROR_FILE_NOT_FOUND) + goto Quit; + + if (!DefineDosDeviceW(0, Drive, Path)) + dwResult = GetLastError(); + else + dwResult = ERROR_SUCCESS; + +Quit: + switch (dwResult) { - // ERROR_IS_SUBSTED - LoadString(GetModuleHandle(NULL), - IDS_DRIVE_ALREADY_SUBSTED, - szFmtString, - ARRAYSIZE(szFmtString)); - _tprintf(szFmtString); - return 1; + case ERROR_SUCCESS: + break; + + case ERROR_INVALID_DRIVE: + case ERROR_INVALID_PARAMETER: + { + LoadStringW(GetModuleHandleW(NULL), + IDS_INVALID_PARAMETER2, + szFmtString, + ARRAYSIZE(szFmtString)); + wprintf(szFmtString, Drive); + return 1; + } + + case ERROR_IS_SUBSTED: + { + LoadStringW(GetModuleHandleW(NULL), + IDS_DRIVE_ALREADY_SUBSTED, + szFmtString, + ARRAYSIZE(szFmtString)); + wprintf(szFmtString); + return 1; + } + + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + { + LoadStringW(GetModuleHandleW(NULL), + IDS_PATH_NOT_FOUND, + szFmtString, + ARRAYSIZE(szFmtString)); + wprintf(szFmtString, Path); + return 1; + } + + case ERROR_ACCESS_DENIED: + { + LoadStringW(GetModuleHandleW(NULL), + IDS_ACCESS_DENIED, + szFmtString, + ARRAYSIZE(szFmtString)); + wprintf(szFmtString, Path); + return 1; + } + + default: + { + PrintError(GetLastError()); + return 1; + } } - Result = DefineDosDevice(0, - Drive, - Path); - if (!Result) - { - PrintError(GetLastError()); - return 1; - } return 0; } -int _tmain(int argc, TCHAR* argv[]) +int wmain(int argc, WCHAR* argv[]) { INT i; - TCHAR szFmtString[RC_STRING_MAX_SIZE] = {0}; + WCHAR szFmtString[RC_STRING_MAX_SIZE] = {0}; for (i = 0; i < argc; i++) { - if (!_tcsicmp(argv[i], _T("/?"))) + if (!_wcsicmp(argv[i], L"/?")) { DisplaySubstUsage(); return 0; @@ -267,11 +356,11 @@ int _tmain(int argc, TCHAR* argv[]) { if (argc >= 2) { - LoadString(GetModuleHandle(NULL), - IDS_INVALID_PARAMETER, - szFmtString, - ARRAYSIZE(szFmtString)); - _tprintf(szFmtString, argv[1]); + LoadStringW(GetModuleHandleW(NULL), + IDS_INVALID_PARAMETER, + szFmtString, + ARRAYSIZE(szFmtString)); + wprintf(szFmtString, argv[1]); return 1; } DumpSubstedDrives(); @@ -280,17 +369,17 @@ int _tmain(int argc, TCHAR* argv[]) if (argc > 3) { - LoadString(GetModuleHandle(NULL), - IDS_INCORRECT_PARAMETER_COUNT, - szFmtString, - ARRAYSIZE(szFmtString)); - _tprintf(szFmtString, argv[3]); + LoadStringW(GetModuleHandleW(NULL), + IDS_INCORRECT_PARAMETER_COUNT, + szFmtString, + ARRAYSIZE(szFmtString)); + wprintf(szFmtString, argv[3]); return 1; } - if (!_tcsicmp(argv[1], _T("/D"))) + if (!_wcsicmp(argv[1], L"/D")) return DeleteSubst(argv[2]); - if (!_tcsicmp(argv[2], _T("/D"))) + if (!_wcsicmp(argv[2], L"/D")) return DeleteSubst(argv[1]); return AddSubst(argv[1], argv[2]); } diff --git a/reactos/base/system/subst/subst.rc b/reactos/base/system/subst/subst.rc index 6e1e7e6b84b..31fd0b43485 100644 --- a/reactos/base/system/subst/subst.rc +++ b/reactos/base/system/subst/subst.rc @@ -2,9 +2,9 @@ #include "resource.h" -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Virtual Drive Utility Version 1.0" -#define REACTOS_STR_INTERNAL_NAME "subst" -#define REACTOS_STR_ORIGINAL_FILENAME "subst.exe" +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Drive Letter Mapper Utility" +#define REACTOS_STR_INTERNAL_NAME "subst" +#define REACTOS_STR_ORIGINAL_FILENAME "subst.exe" #include /* UTF-8 */