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

Last change on this file since 3693 was 3693, checked in by phaller, 25 years ago

Fix: (most stupid!!!) memory leaks in directory.cpp

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