ReactOS 0.4.16-dev-2549-g22ce5b1
subst.c File Reference
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <conutils.h>
#include "resource.h"
Include dependency graph for subst.c:

Go to the source code of this file.

Functions

VOID PrintError (IN DWORD ErrCode)
 
ULONG QuerySubstedDrive (IN WCHAR DriveLetter, IN OUT PWSTR *TargetPath OPTIONAL, IN OUT PULONG Size)
 
VOID DumpSubstedDrives (VOID)
 
INT DeleteSubst (IN PWSTR Drive)
 
INT AddSubst (IN PWSTR Drive, IN PWSTR Path)
 
int wmain (int argc, WCHAR *argv[])
 

Function Documentation

◆ AddSubst()

INT AddSubst ( IN PWSTR  Drive,
IN PWSTR  Path 
)

Definition at line 215 of file subst.c.

216{
217 DWORD dwResult, dwPathAttr;
218
219 if ((wcslen(Drive) != 2) || (Drive[1] != L':'))
220 {
221 dwResult = ERROR_INVALID_PARAMETER;
222 goto Quit;
223 }
224
225 /*
226 * Even if DefineDosDevice allows to map files to drive letters (yes yes!!)
227 * it is not the purpose of SUBST to allow that. Therefore check whether
228 * the given path exists and really is a path to a directory, and if not,
229 * just fail with an error.
230 */
231 dwPathAttr = GetFileAttributesW(Path);
232 if ( (dwPathAttr == INVALID_FILE_ATTRIBUTES) ||
233 !(dwPathAttr & FILE_ATTRIBUTE_DIRECTORY) )
234 {
235 dwResult = ERROR_PATH_NOT_FOUND;
236 goto Quit;
237 }
238
239 /*
240 * QuerySubstedDrive (via QueryDosDevice) returns ERROR_FILE_NOT_FOUND only
241 * if there is no already existing drive mapping. For all other results
242 * (existing drive, be it already subst'ed or not, or other errors...)
243 * no attempt at defining a drive mapping should be done.
244 */
245 dwResult = QuerySubstedDrive(Drive[0], NULL, NULL);
246 if (dwResult != ERROR_FILE_NOT_FOUND)
247 goto Quit;
248
249 if (!DefineDosDeviceW(0, Drive, Path))
250 dwResult = GetLastError();
251 else
252 dwResult = ERROR_SUCCESS;
253
254Quit:
255 switch (dwResult)
256 {
257 case ERROR_SUCCESS:
258 break;
259
262 {
264 return 1;
265 }
266
267 case ERROR_IS_SUBSTED:
268 {
270 return 1;
271 }
272
275 {
277 return 1;
278 }
279
281 {
283 return 1;
284 }
285
286 default:
287 {
289 return 1;
290 }
291 }
292
293 return 0;
294}
PRTL_UNICODE_STRING_BUFFER Path
PWCHAR Drive
Definition: chkdsk.c:73
#define IDS_PATH_NOT_FOUND
Definition: resource.h:11
#define IDS_INVALID_PARAMETER2
Definition: resource.h:10
#define IDS_DRIVE_ALREADY_SUBSTED
Definition: resource.h:13
#define IDS_ACCESS_DENIED
Definition: resource.h:12
void ConResPrintf(FILE *fp, UINT nID,...)
#define StdErr
Definition: conutils_noros.h:7
void ConResPuts(FILE *fp, UINT nID)
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
BOOL WINAPI DefineDosDeviceW(DWORD dwFlags, LPCWSTR lpDeviceName, LPCWSTR lpTargetPath)
Definition: dosdev.c:232
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
#define L(x)
Definition: resources.c:13
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
ULONG QuerySubstedDrive(IN WCHAR DriveLetter, IN OUT PWSTR *TargetPath OPTIONAL, IN OUT PULONG Size)
Definition: subst.c:51
VOID PrintError(IN DWORD ErrCode)
Definition: subst.c:24
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_IS_SUBSTED
Definition: winerror.h:329
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define ERROR_INVALID_DRIVE
Definition: winerror.h:240

Referenced by wmain().

◆ DeleteSubst()

INT DeleteSubst ( IN PWSTR  Drive)

Definition at line 165 of file subst.c.

166{
167 DWORD dwResult;
168
169 if ((wcslen(Drive) != 2) || (Drive[1] != L':'))
170 {
171 dwResult = ERROR_INVALID_PARAMETER;
172 goto Quit;
173 }
174
176 {
177 dwResult = ERROR_INVALID_PARAMETER;
178 goto Quit;
179 }
180
182 dwResult = GetLastError();
183 else
184 dwResult = ERROR_SUCCESS;
185
186Quit:
187 switch (dwResult)
188 {
189 case ERROR_SUCCESS:
190 break;
191
192 // case ERROR_INVALID_DRIVE:
194 {
196 return 1;
197 }
198
200 {
202 return 1;
203 }
204
205 default:
206 {
208 return 1;
209 }
210 }
211
212 return 0;
213}
#define DDD_REMOVE_DEFINITION
Definition: winbase.h:504

Referenced by wmain().

◆ DumpSubstedDrives()

VOID DumpSubstedDrives ( VOID  )

Definition at line 139 of file subst.c.

140{
141 WCHAR DriveLetter;
142 PWSTR lpTargetPath = NULL;
144 UCHAR i = 0;
145
147 lpTargetPath = (PWSTR)HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
148 if (!lpTargetPath)
149 return;
150
151 while (i < 26)
152 {
153 DriveLetter = L'A' + i;
154 if (QuerySubstedDrive(DriveLetter, &lpTargetPath, &dwSize) == ERROR_IS_SUBSTED)
155 {
156 ConPrintf(StdOut, L"%c:\\: => %s\n", DriveLetter, lpTargetPath + 4);
157 }
158
159 i++;
160 }
161
162 HeapFree(GetProcessHeap(), 0, lpTargetPath);
163}
void ConPrintf(FILE *fp, LPCWSTR psz,...)
#define StdOut
Definition: conutils_noros.h:6
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by wmain().

◆ PrintError()

VOID PrintError ( IN DWORD  ErrCode)

Definition at line 24 of file subst.c.

25{
26 // DWORD dwLength = 0;
27 PWSTR pMsgBuf = NULL;
28
29#if 0
30 if (ErrCode == ERROR_SUCCESS)
31 return;
32#endif
33
34 /* Retrieve the message string without appending extra newlines */
35 // dwLength =
38 NULL,
39 ErrCode,
41 (PWSTR)&pMsgBuf,
42 0, NULL);
43 if (pMsgBuf /* && dwLength */)
44 {
46 ErrCode, pMsgBuf);
47 LocalFree(pMsgBuf);
48 }
49}
#define IDS_FAILED_WITH_ERRORCODE
Definition: resource.h:6
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
#define FORMAT_MESSAGE_MAX_WIDTH_MASK
Definition: winbase.h:402
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:397
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:400
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:396

Referenced by AddSubst(), and DeleteSubst().

◆ QuerySubstedDrive()

ULONG QuerySubstedDrive ( IN WCHAR  DriveLetter,
IN OUT PWSTR *TargetPath  OPTIONAL,
IN OUT PULONG  Size 
)

Definition at line 51 of file subst.c.

54{
56 WCHAR Drive[] = L"A:";
57 DWORD dwSize, CharCount = 0;
58 PWSTR lpTargetPath = NULL, tmp;
59
60 Drive[0] = DriveLetter;
61
62 /* Check whether the user has given a pointer to a target path buffer */
63 if (!TargetPath)
64 {
65 /* No, therefore use a local buffer */
67 lpTargetPath = (PWSTR)HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
68 if (!lpTargetPath)
70 }
71 else
72 {
73 /* Just use the user-given pointer to a buffer; Size should point to a valid ULONG */
74 if (!Size)
76
77 lpTargetPath = *TargetPath;
78 dwSize = *Size;
79 }
80
81Retry:
82 /* Try querying DOS device information */
83 CharCount = QueryDosDeviceW(Drive, lpTargetPath, dwSize);
84 if (!CharCount)
86
87 if (!CharCount && (Result == ERROR_INSUFFICIENT_BUFFER))
88 {
89 /* Reallocate the buffer with double size */
90 dwSize *= 2;
91 tmp = (PWSTR)HeapReAlloc(GetProcessHeap(), 0, lpTargetPath, dwSize * sizeof(WCHAR));
92 if (!tmp)
93 {
94 /* Memory problem, bail out */
95 CharCount = 0;
97 }
98 else
99 {
100 /* Retry again */
101 lpTargetPath = tmp;
102 goto Retry;
103 }
104 }
105
106 if (CharCount)
107 {
108 if ( wcsncmp(lpTargetPath, L"\\??\\", 4) == 0 &&
109 ( (lpTargetPath[4] >= L'A' && lpTargetPath[4] <= L'Z') ||
110 (lpTargetPath[4] >= L'a' && lpTargetPath[4] <= L'z') ) )
111 {
112 /* The drive exists and is SUBSTed */
114 }
115#if 0
116 else
117 {
118 /* The drive exists but is not SUBSTed */
120 }
121#endif
122 }
123
124 if (!TargetPath)
125 {
126 /* Free the local buffer */
127 HeapFree(GetProcessHeap(), 0, lpTargetPath);
128 }
129 else
130 {
131 /* Update the user-given pointers */
132 *TargetPath = lpTargetPath;
133 *Size = dwSize;
134 }
135
136 return Result;
137}
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define HeapReAlloc
Definition: compat.h:734
DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:542
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:518
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by AddSubst(), DeleteSubst(), and DumpSubstedDrives().

◆ wmain()

int wmain ( int  argc,
WCHAR argv[] 
)

Definition at line 296 of file subst.c.

297{
298 INT i;
299
300 /* Initialize the Console Standard Streams */
302
303 for (i = 0; i < argc; i++)
304 {
305 if (!_wcsicmp(argv[i], L"/?"))
306 {
308 return 0;
309 }
310 }
311
312 if (argc < 3)
313 {
314 if (argc >= 2)
315 {
317 return 1;
318 }
320 return 0;
321 }
322
323 if (argc > 3)
324 {
326 return 1;
327 }
328
329 if (!_wcsicmp(argv[1], L"/D"))
330 return DeleteSubst(argv[2]);
331 if (!_wcsicmp(argv[2], L"/D"))
332 return DeleteSubst(argv[1]);
333 return AddSubst(argv[1], argv[2]);
334}
#define IDS_USAGE
Definition: resource.h:3
#define IDS_INCORRECT_PARAMETER_COUNT
Definition: resource.h:8
#define IDS_INVALID_PARAMETER
Definition: resource.h:9
#define ConInitStdStreams()
Definition: conutils_noros.h:5
MonoAssembly int argc
Definition: metahost.c:107
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:159
#define argv
Definition: mplay32.c:18
VOID DumpSubstedDrives(VOID)
Definition: subst.c:139
INT DeleteSubst(IN PWSTR Drive)
Definition: subst.c:165
INT AddSubst(IN PWSTR Drive, IN PWSTR Path)
Definition: subst.c:215
int32_t INT
Definition: typedefs.h:58