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

Last change on this file since 3779 was 3779, checked in by sandervl, 25 years ago

MN: lstrcpyn fixes in directory.cpp

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