source: trunk/src/kernel32/directory.cpp@ 2308

Last change on this file since 2308 was 2232, checked in by sandervl, 26 years ago

SetCurrentDirectory check + InstallDate registry key fix

File size: 15.6 KB
Line 
1/* $Id: directory.cpp,v 1.14 1999-12-28 22:08:56 sandervl Exp $ */
2
3/*
4 * Win32 Directory functions for OS/2
5 *
6 * Copyright 1998 Sander van Leeuwen
7 *
8 * Parts based on Wine code (991031) (files\directory.c)
9 *
10 * DOS directories functions
11 *
12 * Copyright 1995 Alexandre Julliard
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17
18
19/*****************************************************************************
20 * Includes *
21 *****************************************************************************/
22
23#include <odin.h>
24#include <odinwrap.h>
25#include <os2win.h>
26#include <stdlib.h>
27#include <unicode.h>
28#include <heapstring.h>
29#include <options.h>
30#include "initterm.h"
31#include <win\file.h>
32#include <string.h>
33#include "oslibdos.h"
34#include "profile.h"
35
36ODINDEBUGCHANNEL(KERNEL32-DIRECTORY)
37
38
39static char DIR_Windows[MAX_PATHNAME_LEN];
40static char DIR_System[MAX_PATHNAME_LEN];
41
42//******************************************************************************
43//******************************************************************************
44char *InternalGetWindowsDirectoryA()
45{
46 return DIR_Windows;
47}
48//******************************************************************************
49//******************************************************************************
50char *InternalGetSystemDirectoryA()
51{
52 return DIR_System;
53}
54//******************************************************************************
55//******************************************************************************
56void InitDirectories()
57{
58 GetWindowsDirectoryA((LPSTR)&DIR_Windows, sizeof(DIR_Windows));
59 GetSystemDirectoryA((LPSTR)&DIR_System, sizeof(DIR_System));
60}
61
62/*****************************************************************************
63 * Name : GetCurrentDirectoryA
64 * Purpose : query the current directory
65 * Parameters:
66 * Variables :
67 * Result :
68 * Remark :
69 * Status :
70 *
71 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
72 *****************************************************************************/
73
74ODINFUNCTION2(UINT, GetCurrentDirectoryA, UINT, nBufferLength,
75 LPSTR, lpBuffer)
76{
77 return O32_GetCurrentDirectory(nBufferLength, lpBuffer);
78}
79
80
81/*****************************************************************************
82 * Name : GetCurrentDirectoryW
83 * Purpose : query the current directory
84 * Parameters:
85 * Variables :
86 * Result :
87 * Remark :
88 * Status :
89 *
90 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
91 *****************************************************************************/
92
93ODINFUNCTION2(UINT, GetCurrentDirectoryW, UINT, nBufferLength,
94 LPWSTR, lpBuffer)
95{
96 char *asciidir = (char *)malloc(nBufferLength+1);
97 int rc;
98
99 rc = O32_GetCurrentDirectory(nBufferLength, asciidir);
100 if(rc != 0)
101 AsciiToUnicode(asciidir, lpBuffer);
102 free(asciidir);
103 return(rc);
104}
105
106
107/*****************************************************************************
108 * Name : SetCurrentDirectoryA
109 * Purpose :
110 * Parameters:
111 * Variables :
112 * Result :
113 * Remark :
114 * Status :
115 *
116 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
117 *****************************************************************************/
118
119
120ODINFUNCTION1(BOOL,SetCurrentDirectoryA,LPCSTR,lpPathName)
121{
122 if(HIWORD(lpPathName) == 0) {
123 SetLastError(ERROR_INVALID_PARAMETER);
124 return FALSE;
125 }
126 int len = strlen(lpPathName);
127 char *tmp=(char *)alloca(len + 1);
128
129 strcpy(tmp, lpPathName);
130 if(tmp[len -1] == '\\')
131 tmp[len -1] = 0;
132
133 dprintf(("SetCurrentDirectoryA %s", tmp));
134 return O32_SetCurrentDirectory((LPSTR)tmp);
135}
136
137
138/*****************************************************************************
139 * Name : SetCurrentDirectoryW
140 * Purpose :
141 * Parameters:
142 * Variables :
143 * Result :
144 * Remark :
145 * Status :
146 *
147 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
148 *****************************************************************************/
149
150ODINFUNCTION1(BOOL,SetCurrentDirectoryW,LPCWSTR,lpPathName)
151{
152 char *asciipath;
153 BOOL rc;
154
155 asciipath = UnicodeToAsciiString((LPWSTR)lpPathName);
156 rc = SetCurrentDirectoryA(asciipath);
157 FreeAsciiString(asciipath);
158 return(rc);
159}
160
161
162/*****************************************************************************
163 * Name : CreateDirectoryA
164 * Purpose :
165 * Parameters:
166 * Variables :
167 * Result :
168 * Remark :
169 * Status :
170 *
171 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
172 *****************************************************************************/
173
174ODINFUNCTION2(BOOL,CreateDirectoryA,LPCSTR, arg1,PSECURITY_ATTRIBUTES,arg2)
175{
176 int len = strlen(arg1);
177 char *tmp=(char *)alloca(len + 1);
178
179 strcpy(tmp, arg1);
180 if(tmp[len -1] == '\\')
181 tmp[len -1] = 0;
182 return O32_CreateDirectory(tmp, arg2);
183}
184
185/*****************************************************************************
186 * Name : CreateDirectoryW
187 * Purpose :
188 * Parameters:
189 * Variables :
190 * Result :
191 * Remark :
192 * Status :
193 *
194 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
195 *****************************************************************************/
196
197ODINFUNCTION2(BOOL,CreateDirectoryW,LPCWSTR, arg1,
198 PSECURITY_ATTRIBUTES,arg2)
199{
200 BOOL rc;
201 char *astring;
202
203 astring = UnicodeToAsciiString((LPWSTR)arg1);
204 rc = CreateDirectoryA(astring, arg2);
205 FreeAsciiString(astring);
206 return(rc);
207}
208
209
210/*****************************************************************************
211 * Name : GetSystemDirectoryA
212 * Purpose :
213 * Parameters:
214 * Variables :
215 * Result :
216 * Remark :
217 * Status :
218 *
219 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
220 *****************************************************************************/
221
222ODINFUNCTION2(UINT,GetSystemDirectoryA,LPSTR,lpBuffer,
223 UINT,uSize)
224{
225 LPSTR lpstrEnv = getenv("WIN32.DIR.SYSTEM"); /* query environment */
226
227 if (lpstrEnv != NULL)
228 {
229 lstrcpynA(lpBuffer, /* copy environment variable to buffer */
230 lpstrEnv,
231 uSize);
232 return (lstrlenA(lpBuffer)); /* return number of copies bytes */
233 }
234 else
235 {
236 int len;
237
238 len = ODIN_PROFILE_GetOdinIniString(ODINDIRECTORIES,"SYSTEM","",lpBuffer,uSize);
239 if (len > 2) {
240 if(lpBuffer[len-1] == '\\') {
241 lpBuffer[len-1] = 0;
242 len--;
243 }
244 return len;
245 }
246 else {//SvL: Use path of kernel32.dll instead of calling Open32 api (which returns \OS2\SYSTEM)
247 lstrcpynA(lpBuffer, kernel32Path, uSize);
248 len = lstrlenA(lpBuffer);;
249 if(lpBuffer[len-1] == '\\') {
250 lpBuffer[len-1] = 0;
251 len--;
252 }
253 return len;
254 }
255 }
256}
257
258
259/*****************************************************************************
260 * Name : GetSystemDirectoryW
261 * Purpose :
262 * Parameters:
263 * Variables :
264 * Result :
265 * Remark :
266 * Status :
267 *
268 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
269 *****************************************************************************/
270
271ODINFUNCTION2(UINT,GetSystemDirectoryW,LPWSTR,lpBuffer,
272 UINT, uSize)
273{
274 char *asciibuffer = (char *)malloc(uSize+1);
275 UINT rc;
276
277 rc = GetSystemDirectoryA(asciibuffer, uSize);
278 if(rc) AsciiToUnicode(asciibuffer, lpBuffer);
279 free(asciibuffer);
280 return(rc);
281}
282
283
284/*****************************************************************************
285 * Name : GetWindowsDirectoryA
286 * Purpose :
287 * Parameters:
288 * Variables :
289 * Result :
290 * Remark :
291 * Status :
292 *
293 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
294 *****************************************************************************/
295
296ODINFUNCTION2(UINT,GetWindowsDirectoryA,LPSTR,lpBuffer,
297 UINT,uSize)
298{
299 LPSTR lpstrEnv = getenv("WIN32.DIR.WINDOWS"); /* query environment */
300
301 if (lpstrEnv != NULL)
302 {
303 lstrcpynA(lpBuffer, /* copy environment variable to buffer */
304 lpstrEnv,
305 uSize);
306 return (lstrlenA(lpBuffer)); /* return number of copies bytes */
307 }
308 else
309 {
310 int len;
311
312 len = ODIN_PROFILE_GetOdinIniString(ODINDIRECTORIES,"WINDOWS","",lpBuffer,uSize);
313 if (len > 2) {
314 if(lpBuffer[len-1] == '\\') {
315 lpBuffer[len-1] = 0;
316 len--;
317 }
318 return len;
319 }
320 else {//SvL: Use path of kernel32.dll instead of calling Open32 api (which returns \OS2\SYSTEM)
321 CHAR buf[255];
322
323 lstrcpynA(buf, kernel32Path, sizeof(buf)-1);
324 strcat(buf, "WIN");
325 O32_CreateDirectory(buf, NULL);
326
327 lstrcpynA(lpBuffer, buf, uSize);
328 len = lstrlenA(lpBuffer);;
329 if(lpBuffer[len-1] == '\\') {
330 lpBuffer[len-1] = 0;
331 len--;
332 }
333 return len;
334 }
335 }
336}
337
338
339/*****************************************************************************
340 * Name : GetWindowsDirectoryW
341 * Purpose :
342 * Parameters:
343 * Variables :
344 * Result :
345 * Remark :
346 * Status :
347 *
348 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
349 *****************************************************************************/
350
351ODINFUNCTION2(UINT,GetWindowsDirectoryW,LPWSTR,lpBuffer,
352 UINT, uSize)
353{
354 char *asciibuffer = (char *)malloc(uSize+1);
355 UINT rc;
356
357 rc = GetWindowsDirectoryA(asciibuffer, uSize);
358 if(rc)
359 AsciiToUnicode(asciibuffer, lpBuffer);
360 free(asciibuffer);
361 return(rc);
362}
363
364
365/*****************************************************************************
366 * Name : RemoveDirectoryA
367 * Purpose :
368 * Parameters:
369 * Variables :
370 * Result :
371 * Remark :
372 * Status :
373 *
374 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
375 *****************************************************************************/
376
377
378ODINFUNCTION1(BOOL,RemoveDirectoryA,LPCSTR,arg1)
379{
380 int len = strlen(arg1);
381 char *tmp=(char *)alloca(len + 1);
382
383 strcpy(tmp, arg1);
384 if(tmp[len -1] == '\\')
385 tmp[len -1] = 0;
386 return O32_RemoveDirectory(tmp);
387}
388
389
390/*****************************************************************************
391 * Name : RemoveDirectoryW
392 * Purpose :
393 * Parameters:
394 * Variables :
395 * Result :
396 * Remark :
397 * Status :
398 *
399 * Author : Patrick Haller [Wed, 1999/09/28 20:44]
400 *****************************************************************************/
401
402ODINFUNCTION1(BOOL,RemoveDirectoryW,LPCWSTR,lpPathName)
403{
404 char *asciipath;
405 BOOL rc;
406
407 asciipath = UnicodeToAsciiString((LPWSTR)lpPathName);
408 rc = RemoveDirectoryA(asciipath);
409 FreeAsciiString(asciipath);
410 return(rc);
411}
412
413/***********************************************************************
414 * DIR_TryModulePath
415 *
416 * Helper function for DIR_SearchPath.
417 */
418static BOOL DIR_TryModulePath( LPCSTR name, char *full_name )
419{
420 char buffer[OFS_MAXPATHNAME];
421 LPSTR p;
422
423 if (!GetModuleFileNameA( 0, buffer, sizeof(buffer) ))
424 buffer[0]='\0';
425
426 if (!(p = strrchr( buffer, '\\' ))) return FALSE;
427 if (sizeof(buffer) - (++p - buffer) <= strlen(name)) return FALSE;
428 strcpy( p, name );
429
430 return OSLibDosSearchPath(OSLIB_SEARCHFILE, NULL, buffer, full_name, MAX_PATHNAME_LEN);
431}
432
433
434/***********************************************************************
435 * DIR_SearchPath
436 *
437 * Implementation of SearchPath32A. 'win32' specifies whether the search
438 * order is Win16 (module path last) or Win32 (module path first).
439 *
440 * FIXME: should return long path names.
441 */
442DWORD DIR_SearchPath( LPCSTR path, LPCSTR name, LPCSTR ext,
443 char *full_name )
444{
445 DWORD len;
446 LPCSTR p;
447 LPSTR tmp = NULL;
448 BOOL ret = TRUE;
449
450 /* First check the supplied parameters */
451
452 p = strrchr( name, '.' );
453 if (p && !strchr( p, '/' ) && !strchr( p, '\\' ))
454 ext = NULL; /* Ignore the specified extension */
455 if ((*name && (name[1] == ':')) ||
456 strchr( name, '/' ) || strchr( name, '\\' ))
457 path = NULL; /* Ignore path if name already contains a path */
458 if (path && !*path) path = NULL; /* Ignore empty path */
459
460 len = strlen(name);
461 if (ext) len += strlen(ext);
462 if (path) len += strlen(path) + 1;
463
464 /* Allocate a buffer for the file name and extension */
465
466 if (path || ext)
467 {
468 if (!(tmp = (LPSTR)HeapAlloc( GetProcessHeap(), 0, len + 1 )))
469 {
470 SetLastError( ERROR_OUTOFMEMORY );
471 return 0;
472 }
473 if (path)
474 {
475 strcpy( tmp, path );
476 strcat( tmp, "\\" );
477 strcat( tmp, name );
478 }
479 else strcpy( tmp, name );
480 if (ext) strcat( tmp, ext );
481 name = tmp;
482 }
483
484 /* If we have an explicit path, everything's easy */
485
486 if (path || (*name && (name[1] == ':')) ||
487 strchr( name, '/' ) || strchr( name, '\\' ))
488 {
489 ret = OSLibDosSearchPath(OSLIB_SEARCHFILE, NULL, (LPSTR)name, full_name, MAX_PATHNAME_LEN);
490 goto done;
491 }
492
493 /* Try the path of the current executable (for Win32 search order) */
494 if (DIR_TryModulePath( name, full_name )) goto done;
495
496 /* Try the current directory */
497 if (OSLibDosSearchPath(OSLIB_SEARCHCURDIR, NULL, (LPSTR)name, full_name, MAX_PATHNAME_LEN))
498 goto done;
499
500 /* Try the Windows system directory */
501 if (OSLibDosSearchPath(OSLIB_SEARCHDIR, (LPSTR)&DIR_System, (LPSTR)name, full_name, MAX_PATHNAME_LEN))
502 goto done;
503
504 /* Try the Windows directory */
505 if (OSLibDosSearchPath(OSLIB_SEARCHDIR, (LPSTR)&DIR_Windows, (LPSTR)name, full_name, MAX_PATHNAME_LEN))
506 goto done;
507
508 /* Try all directories in path */
509 ret = OSLibDosSearchPath(OSLIB_SEARCHENV, "PATH", (LPSTR)name, full_name, MAX_PATHNAME_LEN);
510
511done:
512 if (tmp) HeapFree( GetProcessHeap(), 0, tmp );
513 return ret;
514}
515
516
517/***********************************************************************
518 * SearchPath32A [KERNEL32.447]
519 *
520 * Searches for a specified file in the search path.
521 *
522 * PARAMS
523 * path [I] Path to search
524 * name [I] Filename to search for.
525 * ext [I] File extension to append to file name. The first
526 * character must be a period. This parameter is
527 * specified only if the filename given does not
528 * contain an extension.
529 * buflen [I] size of buffer, in characters
530 * buffer [O] buffer for found filename
531 * lastpart [O] address of pointer to last used character in
532 * buffer (the final '\')
533 *
534 * RETURNS
535 * Success: length of string copied into buffer, not including
536 * terminating null character. If the filename found is
537 * longer than the length of the buffer, the length of the
538 * filename is returned.
539 * Failure: Zero
540 *
541 * NOTES
542 * Should call SetLastError(but currently doesn't).
543 */
544DWORD WINAPI SearchPathA(LPCSTR path, LPCSTR name, LPCSTR ext, DWORD buflen,
545 LPSTR buffer, LPSTR *lastpart )
546{
547 char full_name[MAX_PATHNAME_LEN];
548
549 if (!DIR_SearchPath( path, name, ext, (LPSTR)full_name )) return 0;
550 lstrcpynA( buffer, (LPSTR)full_name, buflen-1);
551 buffer[buflen-2] = 0;
552 SetLastError(0);
553 return strlen(buffer);
554}
555
556
557/***********************************************************************
558 * SearchPath32W (KERNEL32.448)
559 */
560DWORD WINAPI SearchPathW(LPCWSTR path, LPCWSTR name, LPCWSTR ext,
561 DWORD buflen, LPWSTR buffer, LPWSTR *lastpart )
562{
563 char full_name[MAX_PATHNAME_LEN];
564
565 LPSTR pathA = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
566 LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
567 LPSTR extA = HEAP_strdupWtoA( GetProcessHeap(), 0, ext );
568 DWORD ret = DIR_SearchPath( pathA, nameA, extA, (LPSTR)full_name );
569 HeapFree( GetProcessHeap(), 0, extA );
570 HeapFree( GetProcessHeap(), 0, nameA );
571 HeapFree( GetProcessHeap(), 0, pathA );
572 if (!ret) return 0;
573
574 lstrcpynAtoW( buffer, full_name, buflen-1 );
575 buffer[buflen-2] = 0;
576 SetLastError(0);
577 return strlen(full_name);
578}
Note: See TracBrowser for help on using the repository browser.