sysdir.inc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2010 by Sven Barth
  4. FPC Pascal system unit for the Native NT API.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {*****************************************************************************
  12. Directory Handling
  13. *****************************************************************************}
  14. procedure do_MkDir(const s: UnicodeString);
  15. var
  16. objattr: TObjectAttributes;
  17. name: TNtUnicodeString;
  18. res: LongInt;
  19. iostatus: TIOStatusBlock;
  20. h: THandle;
  21. begin
  22. SysUnicodeStringToNtStr(name, s);
  23. { first we try to create a directory object }
  24. SysInitializeObjectAttributes(objattr, @name, OBJ_PERMANENT, 0, Nil);
  25. res := NtCreateDirectoryObject(@h, 0, @objattr);
  26. if res <> STATUS_OBJECT_TYPE_MISMATCH then begin
  27. if res = STATUS_SUCCESS then
  28. NtClose(h);
  29. errno := res;
  30. Errno2InoutRes;
  31. SysFreeNtStr(name);
  32. Exit;
  33. end;
  34. { so the parent directory isn't a directory object... retry as normal file
  35. object }
  36. objattr.Attributes := 0; // OBJ_PERMANENT is not valid for file objects
  37. { the flags are based on ReactOS' CreateDirectoryW except the missing LIST
  38. access }
  39. res := NtCreateFile(@h, NT_SYNCHRONIZE, @objattr, @iostatus, Nil,
  40. FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ or FILE_SHARE_WRITE,
  41. FILE_CREATE, FILE_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT,
  42. Nil, 0);
  43. if res = STATUS_SUCCESS then
  44. NtClose(h);
  45. errno := res;
  46. Errno2InOutRes;
  47. SysFreeNtStr(name);
  48. end;
  49. procedure do_RmDir(const s: UnicodeString);
  50. var
  51. ntstr: TNtUnicodeString;
  52. objattr: TObjectAttributes;
  53. iostatus: TIOStatusBlock;
  54. h: THandle;
  55. disp: TFileDispositionInformation;
  56. res: LongInt;
  57. begin
  58. if s = '.' then
  59. begin
  60. InOutRes := 16;
  61. exit;
  62. end;
  63. if s = '..' then
  64. begin
  65. InOutRes := 5;
  66. exit;
  67. end;
  68. SysUnicodeStringToNtStr(ntstr, s);
  69. SysInitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
  70. res := NtOpenDirectoryObject(@h, STANDARD_RIGHTS_REQUIRED, @objattr);
  71. if res >= 0 then begin
  72. { this is a directory object, so just make it temporary }
  73. {$message warning 'Add check for subdirectories'}
  74. res := NtMakeTemporaryObject(h);
  75. NtClose(h);
  76. errno := res;
  77. Errno2InoutRes;
  78. SysFreeNtStr(ntstr);
  79. end else
  80. if res = STATUS_OBJECT_TYPE_MISMATCH then begin
  81. { this is a file directory or file, so do it like RemoveDirectoryW }
  82. res := NtCreateFile(@h, NT_DELETE or NT_SYNCHRONIZE, @objattr, @iostatus, Nil,
  83. 0, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
  84. FILE_OPEN, FILE_DIRECTORY_FILE or FILE_SYNCHRONOUS_IO_NONALERT,
  85. Nil, 0);
  86. if res >= 0 then begin
  87. disp.DeleteFile := True;
  88. { NtDeleteFile does not work here... }
  89. res := NtSetInformationFile(h, @iostatus, @disp,
  90. SizeOf(TFileDispositionInformation), FileDispositionInformation);
  91. NtClose(h);
  92. end;
  93. end;
  94. SysFreeNtStr(ntstr);
  95. errno := res;
  96. Errno2InoutRes;
  97. end;
  98. procedure do_ChDir(const s: UnicodeString);
  99. begin
  100. { for now this is not supported }
  101. InOutRes := 3;
  102. end;
  103. procedure do_GetDir(DriveNr: byte; var Dir: UnicodeString);
  104. begin
  105. { for now we return simply the root directory }
  106. Dir := DirectorySeparator;
  107. end;