Source code of Windows XP (NT5)
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.

360 lines
9.8 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. handle.c
  5. Abstract:
  6. This module implements the Win32 handle management services.
  7. Author:
  8. Mark Lucovsky (markl) 21-Sep-1990
  9. Revision History:
  10. --*/
  11. #include "basedll.h"
  12. BOOL
  13. CloseHandle(
  14. HANDLE hObject
  15. )
  16. /*++
  17. Routine Description:
  18. An open handle to any object can be closed using CloseHandle.
  19. This is a generic function and operates on the following object
  20. types:
  21. - Process Object
  22. - Thread Object
  23. - Mutex Object
  24. - Event Object
  25. - Semaphore Object
  26. - File Object
  27. Please note that Module Objects are not in this list.
  28. Closing an open handle to an object causes the handle to become
  29. invalid and the HandleCount of the associated object to be
  30. decremented and object retention checks to be performed. Once the
  31. last open handle to an object is closed, the object is removed from
  32. the system.
  33. Arguments:
  34. hObject - An open handle to an object.
  35. Return Value:
  36. TRUE - The operation was successful.
  37. FALSE/NULL - The operation failed. Extended error status is available
  38. using GetLastError.
  39. --*/
  40. {
  41. NTSTATUS Status;
  42. PPEB Peb;
  43. Peb = NtCurrentPeb();
  44. switch( HandleToUlong(hObject) ) {
  45. case STD_INPUT_HANDLE: hObject = Peb->ProcessParameters->StandardInput;
  46. break;
  47. case STD_OUTPUT_HANDLE: hObject = Peb->ProcessParameters->StandardOutput;
  48. break;
  49. case STD_ERROR_HANDLE: hObject = Peb->ProcessParameters->StandardError;
  50. break;
  51. }
  52. if (CONSOLE_HANDLE(hObject)) {
  53. return CloseConsoleHandle(hObject);
  54. }
  55. Status = NtClose(hObject);
  56. if ( NT_SUCCESS(Status) ) {
  57. return TRUE;
  58. }
  59. else {
  60. BaseSetLastNTError(Status);
  61. return FALSE;
  62. }
  63. }
  64. BOOL
  65. DuplicateHandle(
  66. HANDLE hSourceProcessHandle,
  67. HANDLE hSourceHandle,
  68. HANDLE hTargetProcessHandle,
  69. LPHANDLE lpTargetHandle,
  70. DWORD dwDesiredAccess,
  71. BOOL bInheritHandle,
  72. DWORD dwOptions
  73. )
  74. /*++
  75. Routine Description:
  76. A duplicate handle can be created with the DuplicateHandle function.
  77. This is a generic function and operates on the following object
  78. types:
  79. - Process Object
  80. - Thread Object
  81. - Mutex Object
  82. - Event Object
  83. - Semaphore Object
  84. - File Object
  85. Please note that Module Objects are not in this list.
  86. This function requires PROCESS_DUP_ACCESS to both the
  87. SourceProcessHandle and the TargetProcessHandle. This function is
  88. used to pass an object handle from one process to another. Once
  89. this call is complete, the target process needs to be informed of
  90. the value of the target handle. The target process can then operate
  91. on the object using this handle value.
  92. Arguments:
  93. hSourceProcessHandle - An open handle to the process that contains the
  94. handle to be duplicated. The handle must have been created with
  95. PROCESS_DUP_HANDLE access to the process.
  96. hSourceHandle - An open handle to any object that is valid in the
  97. context of the source process.
  98. hTargetProcessHandle - An open handle to the process that is to
  99. receive the duplicated handle. The handle must have been
  100. created with PROCESS_DUP_HANDLE access to the process.
  101. lpTargetHandle - A pointer to a variable which receives the new handle
  102. that points to the same object as SourceHandle does. This
  103. handle value is valid in the context of the target process.
  104. dwDesiredAccess - The access requested to for the new handle. This
  105. parameter is ignored if the DUPLICATE_SAME_ACCESS option is
  106. specified.
  107. bInheritHandle - Supplies a flag that if TRUE, marks the target
  108. handle as inheritable. If this is the case, then the target
  109. handle will be inherited to new processes each time the target
  110. process creates a new process using CreateProcess.
  111. dwOptions - Specifies optional behaviors for the caller.
  112. Options Flags:
  113. DUPLICATE_CLOSE_SOURCE - The SourceHandle will be closed by
  114. this service prior to returning to the caller. This occurs
  115. regardless of any error status returned.
  116. DUPLICATE_SAME_ACCESS - The DesiredAccess parameter is ignored
  117. and instead the GrantedAccess associated with SourceHandle
  118. is used as the DesiredAccess when creating the TargetHandle.
  119. Return Value:
  120. TRUE - The operation was successful.
  121. FALSE/NULL - The operation failed. Extended error status is available
  122. using GetLastError.
  123. --*/
  124. {
  125. NTSTATUS Status;
  126. PPEB Peb;
  127. Peb = NtCurrentPeb();
  128. switch( HandleToUlong(hSourceHandle) ) {
  129. case STD_INPUT_HANDLE: hSourceHandle = Peb->ProcessParameters->StandardInput;
  130. break;
  131. case STD_OUTPUT_HANDLE: hSourceHandle = Peb->ProcessParameters->StandardOutput;
  132. break;
  133. case STD_ERROR_HANDLE: hSourceHandle = Peb->ProcessParameters->StandardError;
  134. break;
  135. }
  136. if (CONSOLE_HANDLE(hSourceHandle) &&
  137. (hSourceHandle != NtCurrentProcess() &&
  138. hSourceHandle != NtCurrentThread()) ) {
  139. HANDLE Target;
  140. if (hSourceProcessHandle != NtCurrentProcess() ||
  141. hTargetProcessHandle != NtCurrentProcess()) {
  142. BaseSetLastNTError(STATUS_INVALID_PARAMETER);
  143. return FALSE;
  144. }
  145. Target = DuplicateConsoleHandle(hSourceHandle,
  146. dwDesiredAccess,
  147. bInheritHandle,
  148. dwOptions
  149. );
  150. if (Target == INVALID_HANDLE_VALUE) {
  151. return FALSE;
  152. }
  153. else {
  154. try {
  155. if ( ARGUMENT_PRESENT(lpTargetHandle) ) {
  156. *lpTargetHandle = Target;
  157. }
  158. }
  159. except (EXCEPTION_EXECUTE_HANDLER) {
  160. return TRUE;
  161. }
  162. return TRUE;
  163. }
  164. }
  165. Status = NtDuplicateObject(
  166. hSourceProcessHandle,
  167. hSourceHandle,
  168. hTargetProcessHandle,
  169. lpTargetHandle,
  170. (ACCESS_MASK)dwDesiredAccess,
  171. bInheritHandle ? OBJ_INHERIT : 0,
  172. dwOptions
  173. );
  174. if ( NT_SUCCESS(Status) ) {
  175. return TRUE;
  176. }
  177. else {
  178. BaseSetLastNTError(Status);
  179. return FALSE;
  180. }
  181. return FALSE;
  182. }
  183. BOOL
  184. GetHandleInformation(
  185. HANDLE hObject,
  186. LPDWORD lpdwFlags
  187. )
  188. {
  189. NTSTATUS Status;
  190. OBJECT_HANDLE_FLAG_INFORMATION HandleInfo;
  191. DWORD Result;
  192. PPEB Peb;
  193. Peb = NtCurrentPeb();
  194. switch( HandleToUlong(hObject) ) {
  195. case STD_INPUT_HANDLE: hObject = Peb->ProcessParameters->StandardInput;
  196. break;
  197. case STD_OUTPUT_HANDLE: hObject = Peb->ProcessParameters->StandardOutput;
  198. break;
  199. case STD_ERROR_HANDLE: hObject = Peb->ProcessParameters->StandardError;
  200. break;
  201. }
  202. if (CONSOLE_HANDLE(hObject)) {
  203. return GetConsoleHandleInformation(hObject,
  204. lpdwFlags
  205. );
  206. }
  207. Status = NtQueryObject( hObject,
  208. ObjectHandleFlagInformation,
  209. &HandleInfo,
  210. sizeof( HandleInfo ),
  211. NULL
  212. );
  213. if (NT_SUCCESS( Status )) {
  214. Result = 0;
  215. if (HandleInfo.Inherit) {
  216. Result |= HANDLE_FLAG_INHERIT;
  217. }
  218. if (HandleInfo.ProtectFromClose) {
  219. Result |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
  220. }
  221. *lpdwFlags = Result;
  222. return TRUE;
  223. }
  224. else {
  225. BaseSetLastNTError( Status );
  226. return FALSE;
  227. }
  228. }
  229. BOOL
  230. SetHandleInformation(
  231. HANDLE hObject,
  232. DWORD dwMask,
  233. DWORD dwFlags
  234. )
  235. {
  236. NTSTATUS Status;
  237. OBJECT_HANDLE_FLAG_INFORMATION HandleInfo;
  238. PPEB Peb;
  239. Peb = NtCurrentPeb();
  240. switch( HandleToUlong(hObject) ) {
  241. case STD_INPUT_HANDLE: hObject = Peb->ProcessParameters->StandardInput;
  242. break;
  243. case STD_OUTPUT_HANDLE: hObject = Peb->ProcessParameters->StandardOutput;
  244. break;
  245. case STD_ERROR_HANDLE: hObject = Peb->ProcessParameters->StandardError;
  246. break;
  247. }
  248. if (CONSOLE_HANDLE(hObject)) {
  249. return SetConsoleHandleInformation(hObject,
  250. dwMask,
  251. dwFlags
  252. );
  253. }
  254. Status = NtQueryObject( hObject,
  255. ObjectHandleFlagInformation,
  256. &HandleInfo,
  257. sizeof( HandleInfo ),
  258. NULL
  259. );
  260. if (NT_SUCCESS( Status )) {
  261. if (dwMask & HANDLE_FLAG_INHERIT) {
  262. HandleInfo.Inherit = (dwFlags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
  263. }
  264. if (dwMask & HANDLE_FLAG_PROTECT_FROM_CLOSE) {
  265. HandleInfo.ProtectFromClose = (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE;
  266. }
  267. Status = NtSetInformationObject( hObject,
  268. ObjectHandleFlagInformation,
  269. &HandleInfo,
  270. sizeof( HandleInfo )
  271. );
  272. if (NT_SUCCESS( Status )) {
  273. return TRUE;
  274. }
  275. }
  276. BaseSetLastNTError( Status );
  277. return FALSE;
  278. }