Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
5.0 KiB

  1. /***
  2. *chdir.c - change directory
  3. *
  4. * Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * This file has the _chdir() function - change current directory.
  8. *
  9. *Revision History:
  10. * 06-06-89 PHG Module created, based on asm version
  11. * 03-07-90 GJF Made calling type _CALLTYPE2 (for now), added #include
  12. * <cruntime.h>, fixed copyright and fixed compiler
  13. * warnings. Also, cleaned up the formatting a bit.
  14. * 03-30-90 GJF Now _CALLTYPE1.
  15. * 07-24-90 SBM Removed '32' from API names
  16. * 09-27-90 GJF New-style function declarator.
  17. * 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
  18. * 12-06-90 SRW Added _CRUISER_ and _WIN32 conditionals.
  19. * 01-16-91 GJF ANSI naming.
  20. * 05-19-92 GJF Revised to support the 'current directory' environment
  21. * variables of Win32/NT.
  22. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  23. * 11-24-93 CFW Rip out Cruiser.
  24. * 11-24-93 CFW No longer store current drive in CRT env strings.
  25. * 12-01-93 CFW Set OS drive letter variables.
  26. * 12-07-93 CFW Wide char enable.
  27. * 01-25-95 GJF New current directory can be a UNC path!
  28. * 02-08-95 JWM Spliced _WIN32 & Mac versions.
  29. * 07-01-96 GJF Replaced defined(_WIN32) with !defined(_MAC). Also,
  30. * detab-ed and cleaned up the format a bit.
  31. * 05-17-99 PML Remove all Macintosh support.
  32. * 04-26-02 GB fixed bug if path is greater then MAX_PATH, i.e. "\\?\"
  33. * prepended to path.
  34. *
  35. *******************************************************************************/
  36. #include <cruntime.h>
  37. #include <oscalls.h>
  38. #include <mtdll.h>
  39. #include <internal.h>
  40. #include <direct.h>
  41. #include <stdlib.h>
  42. #include <tchar.h>
  43. #include <malloc.h>
  44. #include <dbgint.h>
  45. /***
  46. *int _chdir(path) - change current directory
  47. *
  48. *Purpose:
  49. * Changes the current working directory to that given in path.
  50. *
  51. *Entry:
  52. * _TSCHAR *path - directory to change to
  53. *
  54. *Exit:
  55. * returns 0 if successful,
  56. * returns -1 and sets errno if unsuccessful
  57. *
  58. *Exceptions:
  59. *
  60. *******************************************************************************/
  61. int __cdecl _tchdir (
  62. const _TSCHAR *path
  63. )
  64. {
  65. _TSCHAR env_var[4];
  66. _TSCHAR abspath[MAX_PATH+1];
  67. _TSCHAR *apath=abspath;
  68. int memfree=0;
  69. int r;
  70. int retval = -1;
  71. if ( SetCurrentDirectory((LPTSTR)path) )
  72. {
  73. /*
  74. * If the new current directory path is NOT a UNC path, we must
  75. * update the OS environment variable specifying the current
  76. * directory for what is now current drive. To do this, get the
  77. * full current directory, build the environment variable string
  78. * and call SetEnvironmentVariable(). We need to do this because
  79. * SetCurrentDirectory does not (i.e., does not update the
  80. * current-directory-on-drive environment variables) and other
  81. * functions (fullpath, spawn, etc) need them to be set.
  82. *
  83. * If associated with a 'drive', the current directory should
  84. * have the form of the example below:
  85. *
  86. * D:\nt\private\mytests
  87. *
  88. * so that the environment variable should be of the form:
  89. *
  90. * =D:=D:\nt\private\mytests
  91. *
  92. */
  93. r = GetCurrentDirectory(MAX_PATH+1,(LPTSTR)apath);
  94. if (r > MAX_PATH) {
  95. __try{
  96. apath=(_TSCHAR *)_alloca((r+1)*sizeof(_TSCHAR));
  97. } __except(EXCEPTION_EXECUTE_HANDLER){
  98. _resetstkoflw();
  99. if ((apath = (_TSCHAR *)_malloc_crt((r+1)*sizeof(_TSCHAR))) == NULL) {
  100. r = 0;
  101. } else {
  102. memfree = 1;
  103. }
  104. }
  105. if (r)
  106. r = GetCurrentDirectory(r+1,(LPTSTR)apath);
  107. }
  108. if (r)
  109. {
  110. /*
  111. * check if it is a UNC name, just return if is
  112. */
  113. if ( ((apath[0] == _T('\\')) || (apath[0] == _T('/'))) &&
  114. (apath[0] == apath[1]) )
  115. retval = 0;
  116. else {
  117. env_var[0] = _T('=');
  118. env_var[1] = (_TSCHAR) _totupper((_TUCHAR)apath[0]);
  119. env_var[2] = _T(':');
  120. env_var[3] = _T('\0');
  121. if ( SetEnvironmentVariable(env_var, apath) )
  122. retval = 0;
  123. }
  124. }
  125. }
  126. _dosmaperr(GetLastError());
  127. if (memfree)
  128. _free_crt(apath);
  129. return retval;
  130. }