1 /*
2 * Object management functions
3 *
4 * Copyright 1999, 2000 Juergen Schmied
5 * Copyright 2005 Vitaliy Margolen
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "config.h"
23
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #ifdef HAVE_IO_H
28 # include <io.h>
29 #endif
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
33
34 #include "ntstatus.h"
35 #define WIN32_NO_STATUS
36 #include "wine/debug.h"
37 #include "windef.h"
38 #include "winternl.h"
39 #include "ntdll_misc.h"
40 #include "wine/server.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
43
44
45 /*
46 * Generic object functions
47 */
48
49 /******************************************************************************
50 * NtQueryObject [NTDLL.@]
51 * ZwQueryObject [NTDLL.@]
52 */
53 NTSTATUS WINAPI NtQueryObject(IN HANDLE handle,
54 IN OBJECT_INFORMATION_CLASS info_class,
55 OUT PVOID ptr, IN ULONG len, OUT PULONG used_len)
56 {
57 NTSTATUS status;
58
59 TRACE("(%p,0x%08x,%p,0x%08x,%p): stub\n",
60 handle, info_class, ptr, len, used_len);
61
62 if (used_len) *used_len = 0;
63
64 switch (info_class)
65 {
66 case ObjectBasicInformation:
67 {
68 POBJECT_BASIC_INFORMATION p = (POBJECT_BASIC_INFORMATION)ptr;
69
70 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
71
72 SERVER_START_REQ( get_object_info )
73 {
74 req->handle = wine_server_obj_handle( handle );
75 status = wine_server_call( req );
76 if (status == STATUS_SUCCESS)
77 {
78 memset( p, 0, sizeof(*p) );
79 p->GrantedAccess = reply->access;
80 p->PointerCount = reply->ref_count;
81 p->HandleCount = 1; /* at least one */
82 if (used_len) *used_len = sizeof(*p);
83 }
84 }
85 SERVER_END_REQ;
86 }
87 break;
88 case ObjectDataInformation:
89 {
90 OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
91
92 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
93
94 SERVER_START_REQ( set_handle_info )
95 {
96 req->handle = wine_server_obj_handle( handle );
97 req->flags = 0;
98 req->mask = 0;
99 status = wine_server_call( req );
100 if (status == STATUS_SUCCESS)
101 {
102 p->InheritHandle = (reply->old_flags & HANDLE_FLAG_INHERIT) ? TRUE : FALSE;
103 p->ProtectFromClose = (reply->old_flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ? TRUE : FALSE;
104 if (used_len) *used_len = sizeof(*p);
105 }
106 }
107 SERVER_END_REQ;
108 }
109 break;
110 default:
111 FIXME("Unsupported information class %u\n", info_class);
112 status = STATUS_NOT_IMPLEMENTED;
113 break;
114 }
115 return status;
116 }
117
118 /******************************************************************
119 * NtSetInformationObject [NTDLL.@]
120 * ZwSetInformationObject [NTDLL.@]
121 *
122 */
123 NTSTATUS WINAPI NtSetInformationObject(IN HANDLE handle,
124 IN OBJECT_INFORMATION_CLASS info_class,
125 IN PVOID ptr, IN ULONG len)
126 {
127 NTSTATUS status;
128
129 TRACE("(%p,0x%08x,%p,0x%08x): stub\n",
130 handle, info_class, ptr, len);
131
132 switch (info_class)
133 {
134 case ObjectDataInformation:
135 {
136 OBJECT_DATA_INFORMATION* p = (OBJECT_DATA_INFORMATION*)ptr;
137
138 if (len < sizeof(*p)) return STATUS_INVALID_BUFFER_SIZE;
139
140 SERVER_START_REQ( set_handle_info )
141 {
142 req->handle = wine_server_obj_handle( handle );
143 req->flags = 0;
144 req->mask = HANDLE_FLAG_INHERIT | HANDLE_FLAG_PROTECT_FROM_CLOSE;
145 if (p->InheritHandle) req->flags |= HANDLE_FLAG_INHERIT;
146 if (p->ProtectFromClose) req->flags |= HANDLE_FLAG_PROTECT_FROM_CLOSE;
147 status = wine_server_call( req );
148 }
149 SERVER_END_REQ;
150 }
151 break;
152 default:
153 FIXME("Unsupported information class %u\n", info_class);
154 status = STATUS_NOT_IMPLEMENTED;
155 break;
156 }
157 return status;
158 }
159
160 /******************************************************************************
161 * NtQuerySecurityObject [NTDLL.@]
162 *
163 * An ntdll analogue to GetKernelObjectSecurity().
164 *
165 */
166 NTSTATUS WINAPI
167 NtQuerySecurityObject(
168 IN HANDLE Object,
169 IN SECURITY_INFORMATION RequestedInformation,
170 OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
171 IN ULONG Length,
172 OUT PULONG ResultLength)
173 {
174 PISECURITY_DESCRIPTOR_RELATIVE psd = pSecurityDescriptor;
175 NTSTATUS status;
176 unsigned int buffer_size = 512;
177 BOOLEAN need_more_memory;
178
179 TRACE("(%p,0x%08x,%p,0x%08x,%p)\n",
180 Object, RequestedInformation, pSecurityDescriptor, Length, ResultLength);
181
182 do
183 {
184 char *buffer = RtlAllocateHeap(GetProcessHeap(), 0, buffer_size);
185 if (!buffer)
186 return STATUS_NO_MEMORY;
187
188 need_more_memory = FALSE;
189
190 SERVER_START_REQ( get_security_object )
191 {
192 req->handle = wine_server_obj_handle( Object );
193 req->security_info = RequestedInformation;
194 wine_server_set_reply( req, buffer, buffer_size );
195 status = wine_server_call( req );
196 if (status == STATUS_SUCCESS)
197 {
198 struct security_descriptor *sd = (struct security_descriptor *)buffer;
199 if (reply->sd_len)
200 {
201 *ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) +
202 sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len;
203 if (Length >= *ResultLength)
204 {
205 psd->Revision = SECURITY_DESCRIPTOR_REVISION;
206 psd->Sbz1 = 0;
207 psd->Control = sd->control | SE_SELF_RELATIVE;
208 psd->Owner = sd->owner_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) : 0;
209 psd->Group = sd->group_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len : 0;
210 psd->Sacl = sd->sacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len : 0;
211 psd->Dacl = sd->dacl_len ? sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sd->owner_len + sd->group_len + sd->sacl_len : 0;
212 /* owner, group, sacl and dacl are the same type as in the server
213 * and in the same order so we copy the memory in one block */
214 memcpy((char *)pSecurityDescriptor + sizeof(SECURITY_DESCRIPTOR_RELATIVE),
215 buffer + sizeof(struct security_descriptor),
216 sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len);
217 }
218 else
219 status = STATUS_BUFFER_TOO_SMALL;
220 }
221 else
222 {
223 *ResultLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
224 if (Length >= *ResultLength)
225 {
226 memset(psd, 0, sizeof(*psd));
227 psd->Revision = SECURITY_DESCRIPTOR_REVISION;
228 psd->Control = SE_SELF_RELATIVE;
229 }
230 else
231 status = STATUS_BUFFER_TOO_SMALL;
232 }
233 }
234 else if (status == STATUS_BUFFER_TOO_SMALL)
235 {
236 buffer_size = reply->sd_len;
237 need_more_memory = TRUE;
238 }
239 }
240 SERVER_END_REQ;
241 RtlFreeHeap(GetProcessHeap(), 0, buffer);
242 } while (need_more_memory);
243
244 return status;
245 }
246
247
248 /******************************************************************************
249 * NtDuplicateObject [NTDLL.@]
250 * ZwDuplicateObject [NTDLL.@]
251 */
252 NTSTATUS WINAPI NtDuplicateObject( HANDLE source_process, HANDLE source,
253 HANDLE dest_process, PHANDLE dest,
254 ACCESS_MASK access, ULONG attributes, ULONG options )
255 {
256 NTSTATUS ret;
257 SERVER_START_REQ( dup_handle )
258 {
259 req->src_process = wine_server_obj_handle( source_process );
260 req->src_handle = wine_server_obj_handle( source );
261 req->dst_process = wine_server_obj_handle( dest_process );
262 req->access = access;
263 req->attributes = attributes;
264 req->options = options;
265
266 if (!(ret = wine_server_call( req )))
267 {
268 if (dest) *dest = wine_server_ptr_handle( reply->handle );
269 if (reply->closed)
270 {
271 if (reply->self)
272 {
273 int fd = server_remove_fd_from_cache( source );
274 if (fd != -1) close( fd );
275 }
276 }
277 else if (options & DUPLICATE_CLOSE_SOURCE)
278 WARN( "failed to close handle %p in process %p\n", source, source_process );
279 }
280 }
281 SERVER_END_REQ;
282 return ret;
283 }
284
285 /**************************************************************************
286 * NtClose [NTDLL.@]
287 *
288 * Close a handle reference to an object.
289 *
290 * PARAMS
291 * Handle [I] handle to close
292 *
293 * RETURNS
294 * Success: ERROR_SUCCESS.
295 * Failure: An NTSTATUS error code.
296 */
297 NTSTATUS WINAPI NtClose( HANDLE Handle )
298 {
299 NTSTATUS ret;
300 int fd = server_remove_fd_from_cache( Handle );
301
302 SERVER_START_REQ( close_handle )
303 {
304 req->handle = wine_server_obj_handle( Handle );
305 ret = wine_server_call( req );
306 }
307 SERVER_END_REQ;
308 if (fd != -1) close( fd );
309 return ret;
310 }
311
312 /*
313 * Directory functions
314 */
315
316 /**************************************************************************
317 * NtOpenDirectoryObject [NTDLL.@]
318 * ZwOpenDirectoryObject [NTDLL.@]
319 *
320 * Open a namespace directory object.
321 *
322 * PARAMS
323 * DirectoryHandle [O] Destination for the new directory handle
324 * DesiredAccess [I] Desired access to the directory
325 * ObjectAttributes [I] Structure describing the directory
326 *
327 * RETURNS
328 * Success: ERROR_SUCCESS.
329 * Failure: An NTSTATUS error code.
330 */
331 NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
332 POBJECT_ATTRIBUTES ObjectAttributes)
333 {
334 NTSTATUS ret;
335 TRACE("(%p,0x%08x)\n", DirectoryHandle, DesiredAccess);
336 dump_ObjectAttributes(ObjectAttributes);
337
338 if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
339 if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
340 /* Have to test it here because server won't know difference between
341 * ObjectName == NULL and ObjectName == "" */
342 if (!ObjectAttributes->ObjectName)
343 {
344 if (ObjectAttributes->RootDirectory)
345 return STATUS_OBJECT_NAME_INVALID;
346 else
347 return STATUS_OBJECT_PATH_SYNTAX_BAD;
348 }
349
350 SERVER_START_REQ(open_directory)
351 {
352 req->access = DesiredAccess;
353 req->attributes = ObjectAttributes->Attributes;
354 req->rootdir = wine_server_obj_handle( ObjectAttributes->RootDirectory );
355 if (ObjectAttributes->ObjectName)
356 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
357 ObjectAttributes->ObjectName->Length);
358 ret = wine_server_call( req );
359 *DirectoryHandle = wine_server_ptr_handle( reply->handle );
360 }
361 SERVER_END_REQ;
362 return ret;
363 }
364
365 /******************************************************************************
366 * NtCreateDirectoryObject [NTDLL.@]
367 * ZwCreateDirectoryObject [NTDLL.@]
368 *
369 * Create a namespace directory object.
370 *
371 * PARAMS
372 * DirectoryHandle [O] Destination for the new directory handle
373 * DesiredAccess [I] Desired access to the directory
374 * ObjectAttributes [I] Structure describing the directory
375 *
376 * RETURNS
377 * Success: ERROR_SUCCESS.
378 * Failure: An NTSTATUS error code.
379 */
380 NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
381 POBJECT_ATTRIBUTES ObjectAttributes)
382 {
383 NTSTATUS ret;
384 TRACE("(%p,0x%08x)\n", DirectoryHandle, DesiredAccess);
385 dump_ObjectAttributes(ObjectAttributes);
386
387 if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
388
389 SERVER_START_REQ(create_directory)
390 {
391 req->access = DesiredAccess;
392 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
393 req->rootdir = wine_server_obj_handle( ObjectAttributes ? ObjectAttributes->RootDirectory : 0 );
394 if (ObjectAttributes && ObjectAttributes->ObjectName)
395 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
396 ObjectAttributes->ObjectName->Length);
397 ret = wine_server_call( req );
398 *DirectoryHandle = wine_server_ptr_handle( reply->handle );
399 }
400 SERVER_END_REQ;
401 return ret;
402 }
403
404 /******************************************************************************
405 * NtQueryDirectoryObject [NTDLL.@]
406 * ZwQueryDirectoryObject [NTDLL.@]
407 *
408 * Read information from a namespace directory.
409 *
410 * PARAMS
411 * handle [I] Handle to a directory object
412 * buffer [O] Buffer to hold the read data
413 * size [I] Size of the buffer in bytes
414 * single_entry [I] If TRUE, return a single entry, if FALSE, return as many as fit in the buffer
415 * restart [I] If TRUE, start scanning from the start, if FALSE, scan from Context
416 * context [I/O] Indicates what point of the directory the scan is at
417 * ret_size [O] Caller supplied storage for the number of bytes written (or NULL)
418 *
419 * RETURNS
420 * Success: ERROR_SUCCESS.
421 * Failure: An NTSTATUS error code.
422 */
423 NTSTATUS WINAPI NtQueryDirectoryObject(HANDLE handle, PDIRECTORY_BASIC_INFORMATION buffer,
424 ULONG size, BOOLEAN single_entry, BOOLEAN restart,
425 PULONG context, PULONG ret_size)
426 {
427 NTSTATUS ret;
428
429 if (restart) *context = 0;
430
431 if (single_entry)
432 {
433 if (size <= sizeof(*buffer) + 2*sizeof(WCHAR)) return STATUS_BUFFER_OVERFLOW;
434
435 SERVER_START_REQ( get_directory_entry )
436 {
437 req->handle = wine_server_obj_handle( handle );
438 req->index = *context;
439 wine_server_set_reply( req, buffer + 1, size - sizeof(*buffer) - 2*sizeof(WCHAR) );
440 if (!(ret = wine_server_call( req )))
441 {
442 buffer->ObjectName.Buffer = (WCHAR *)(buffer + 1);
443 buffer->ObjectName.Length = reply->name_len;
444 buffer->ObjectName.MaximumLength = reply->name_len + sizeof(WCHAR);
445 buffer->ObjectTypeName.Buffer = (WCHAR *)(buffer + 1) + reply->name_len/sizeof(WCHAR) + 1;
446 buffer->ObjectTypeName.Length = wine_server_reply_size( reply ) - reply->name_len;
447 buffer->ObjectTypeName.MaximumLength = buffer->ObjectTypeName.Length + sizeof(WCHAR);
448 /* make room for the terminating null */
449 memmove( buffer->ObjectTypeName.Buffer, buffer->ObjectTypeName.Buffer - 1,
450 buffer->ObjectTypeName.Length );
451 buffer->ObjectName.Buffer[buffer->ObjectName.Length/sizeof(WCHAR)] = 0;
452 buffer->ObjectTypeName.Buffer[buffer->ObjectTypeName.Length/sizeof(WCHAR)] = 0;
453 (*context)++;
454 }
455 }
456 SERVER_END_REQ;
457 if (ret_size)
458 *ret_size = buffer->ObjectName.MaximumLength + buffer->ObjectTypeName.MaximumLength + sizeof(*buffer);
459 }
460 else
461 {
462 FIXME("multiple entries not implemented\n");
463 ret = STATUS_NOT_IMPLEMENTED;
464 }
465
466 return ret;
467 }
468
469 /*
470 * Link objects
471 */
472
473 /******************************************************************************
474 * NtOpenSymbolicLinkObject [NTDLL.@]
475 * ZwOpenSymbolicLinkObject [NTDLL.@]
476 *
477 * Open a namespace symbolic link object.
478 *
479 * PARAMS
480 * LinkHandle [O] Destination for the new symbolic link handle
481 * DesiredAccess [I] Desired access to the symbolic link
482 * ObjectAttributes [I] Structure describing the symbolic link
483 *
484 * RETURNS
485 * Success: ERROR_SUCCESS.
486 * Failure: An NTSTATUS error code.
487 */
488 NTSTATUS WINAPI NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, IN ACCESS_MASK DesiredAccess,
489 IN POBJECT_ATTRIBUTES ObjectAttributes)
490 {
491 NTSTATUS ret;
492 TRACE("(%p,0x%08x,%p)\n",LinkHandle, DesiredAccess, ObjectAttributes);
493 dump_ObjectAttributes(ObjectAttributes);
494
495 if (!LinkHandle) return STATUS_ACCESS_VIOLATION;
496 if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
497 /* Have to test it here because server won't know difference between
498 * ObjectName == NULL and ObjectName == "" */
499 if (!ObjectAttributes->ObjectName)
500 {
501 if (ObjectAttributes->RootDirectory)
502 return STATUS_OBJECT_NAME_INVALID;
503 else
504 return STATUS_OBJECT_PATH_SYNTAX_BAD;
505 }
506
507 SERVER_START_REQ(open_symlink)
508 {
509 req->access = DesiredAccess;
510 req->attributes = ObjectAttributes->Attributes;
511 req->rootdir = wine_server_obj_handle( ObjectAttributes->RootDirectory );
512 if (ObjectAttributes->ObjectName)
513 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
514 ObjectAttributes->ObjectName->Length);
515 ret = wine_server_call( req );
516 *LinkHandle = wine_server_ptr_handle( reply->handle );
517 }
518 SERVER_END_REQ;
519 return ret;
520 }
521
522 /******************************************************************************
523 * NtCreateSymbolicLinkObject [NTDLL.@]
524 * ZwCreateSymbolicLinkObject [NTDLL.@]
525 *
526 * Open a namespace symbolic link object.
527 *
528 * PARAMS
529 * SymbolicLinkHandle [O] Destination for the new symbolic link handle
530 * DesiredAccess [I] Desired access to the symbolic link
531 * ObjectAttributes [I] Structure describing the symbolic link
532 * TargetName [I] Name of the target symbolic link points to
533 *
534 * RETURNS
535 * Success: ERROR_SUCCESS.
536 * Failure: An NTSTATUS error code.
537 */
538 NTSTATUS WINAPI NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle,IN ACCESS_MASK DesiredAccess,
539 IN POBJECT_ATTRIBUTES ObjectAttributes,
540 IN PUNICODE_STRING TargetName)
541 {
542 NTSTATUS ret;
543 TRACE("(%p,0x%08x,%p, -> %s)\n", SymbolicLinkHandle, DesiredAccess, ObjectAttributes,
544 debugstr_us(TargetName));
545 dump_ObjectAttributes(ObjectAttributes);
546
547 if (!SymbolicLinkHandle || !TargetName) return STATUS_ACCESS_VIOLATION;
548 if (!TargetName->Buffer) return STATUS_INVALID_PARAMETER;
549
550 SERVER_START_REQ(create_symlink)
551 {
552 req->access = DesiredAccess;
553 req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
554 req->rootdir = wine_server_obj_handle( ObjectAttributes ? ObjectAttributes->RootDirectory : 0 );
555 if (ObjectAttributes && ObjectAttributes->ObjectName)
556 {
557 req->name_len = ObjectAttributes->ObjectName->Length;
558 wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
559 ObjectAttributes->ObjectName->Length);
560 }
561 else
562 req->name_len = 0;
563 wine_server_add_data(req, TargetName->Buffer, TargetName->Length);
564 ret = wine_server_call( req );
565 *SymbolicLinkHandle = wine_server_ptr_handle( reply->handle );
566 }
567 SERVER_END_REQ;
568 return ret;
569 }
570
571 /******************************************************************************
572 * NtQuerySymbolicLinkObject [NTDLL.@]
573 * ZwQuerySymbolicLinkObject [NTDLL.@]
574 *
575 * Query a namespace symbolic link object target name.
576 *
577 * PARAMS
578 * LinkHandle [I] Handle to a symbolic link object
579 * LinkTarget [O] Destination for the symbolic link target
580 * ReturnedLength [O] Size of returned data
581 *
582 * RETURNS
583 * Success: ERROR_SUCCESS.
584 * Failure: An NTSTATUS error code.
585 */
586 NTSTATUS WINAPI NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, IN OUT PUNICODE_STRING LinkTarget,
587 OUT PULONG ReturnedLength OPTIONAL)
588 {
589 NTSTATUS ret;
590 TRACE("(%p,%p,%p)\n", LinkHandle, LinkTarget, ReturnedLength);
591
592 if (!LinkTarget) return STATUS_ACCESS_VIOLATION;
593
594 SERVER_START_REQ(query_symlink)
595 {
596 req->handle = wine_server_obj_handle( LinkHandle );
597 wine_server_set_reply( req, LinkTarget->Buffer, LinkTarget->MaximumLength );
598 if (!(ret = wine_server_call( req )))
599 {
600 LinkTarget->Length = wine_server_reply_size(reply);
601 if (ReturnedLength) *ReturnedLength = LinkTarget->Length;
602 }
603 }
604 SERVER_END_REQ;
605 return ret;
606 }
607
608 /******************************************************************************
609 * NtAllocateUuids [NTDLL.@]
610 */
611 NTSTATUS WINAPI NtAllocateUuids(
612 PULARGE_INTEGER Time,
613 PULONG Range,
614 PULONG Sequence)
615 {
616 FIXME("(%p,%p,%p), stub.\n", Time, Range, Sequence);
617 return 0;
618 }
619
620 /**************************************************************************
621 * NtMakeTemporaryObject [NTDLL.@]
622 * ZwMakeTemporaryObject [NTDLL.@]
623 *
624 * Make a permanent object temporary.
625 *
626 * PARAMS
627 * Handle [I] handle to permanent object
628 *
629 * RETURNS
630 * Success: STATUS_SUCCESS.
631 * Failure: An NTSTATUS error code.
632 */
633 NTSTATUS WINAPI NtMakeTemporaryObject( HANDLE Handle )
634 {
635 FIXME("(%p), stub.\n", Handle);
636 return STATUS_SUCCESS;
637 }
638
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.