some __stdcall fixes in ntoskrnl and ntdll
[reactos.git] / reactos / ntoskrnl / io / symlink.c
1 /* $Id: symlink.c,v 1.9 1999/08/29 06:59:08 ea Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/symlink.c
6 * PURPOSE: Implements symbolic links
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <wchar.h>
17
18 #define NDEBUG
19 #include <internal/debug.h>
20
21 /* GLOBALS ******************************************************************/
22
23 typedef
24 struct
25 {
26 CSHORT Type;
27 CSHORT Size;
28 UNICODE_STRING TargetName;
29 OBJECT_ATTRIBUTES Target;
30
31 } SYMLNK_OBJECT, *PSYMLNK_OBJECT;
32
33
34 POBJECT_TYPE
35 IoSymbolicLinkType = NULL;
36
37 /* FUNCTIONS *****************************************************************/
38
39
40 /**********************************************************************
41 * NAME INTERNAL
42 * IopCreateSymbolicLink
43 *
44 * DESCRIPTION
45 *
46 * ARGUMENTS
47 *
48 * RETURNN VALUE
49 * Status.
50 *
51 * REVISIONS
52 */
53 NTSTATUS
54 IopCreateSymbolicLink (
55 PVOID Object,
56 PVOID Parent,
57 PWSTR RemainingPath,
58 POBJECT_ATTRIBUTES ObjectAttributes
59 )
60 {
61 if ( (Parent != NULL)
62 && (RemainingPath != NULL)
63 )
64 {
65 ObAddEntryDirectory(
66 Parent,
67 Object,
68 RemainingPath + 1
69 );
70 }
71 return STATUS_SUCCESS;
72 }
73
74
75 /**********************************************************************
76 * NAME INTERNAL
77 * IopParseSymbolicLink
78 *
79 * DESCRIPTION
80 *
81 * ARGUMENTS
82 *
83 * RETURNN VALUE
84 *
85 * REVISIONS
86 */
87 PVOID
88 IopParseSymbolicLink (
89 PVOID Object,
90 PWSTR * RemainingPath
91 )
92 {
93 NTSTATUS Status;
94 PSYMLNK_OBJECT SymlinkObject = (PSYMLNK_OBJECT) Object;
95 PVOID ReturnedObject;
96
97 Status = ObReferenceObjectByName(
98 SymlinkObject->Target.ObjectName,
99 0,
100 NULL,
101 STANDARD_RIGHTS_REQUIRED,
102 NULL,
103 UserMode,
104 NULL,
105 & ReturnedObject
106 );
107 if (NT_SUCCESS(Status))
108 {
109 return ReturnedObject;
110 }
111 return NULL;
112 }
113
114
115 /**********************************************************************
116 * NAME INTERNAL
117 * IoInitSymbolicLinkImplementation
118 *
119 * DESCRIPTION
120 *
121 * ARGUMENTS
122 * None.
123 *
124 * RETURNN VALUE
125 * None.
126 *
127 * REVISIONS
128 */
129 VOID
130 IoInitSymbolicLinkImplementation (VOID)
131 {
132 ANSI_STRING AnsiString;
133
134 IoSymbolicLinkType = ExAllocatePool(
135 NonPagedPool,
136 sizeof (OBJECT_TYPE)
137 );
138
139 IoSymbolicLinkType->TotalObjects = 0;
140 IoSymbolicLinkType->TotalHandles = 0;
141 IoSymbolicLinkType->MaxObjects = ULONG_MAX;
142 IoSymbolicLinkType->MaxHandles = ULONG_MAX;
143 IoSymbolicLinkType->PagedPoolCharge = 0;
144 IoSymbolicLinkType->NonpagedPoolCharge = sizeof (SYMLNK_OBJECT);
145 IoSymbolicLinkType->Dump = NULL;
146 IoSymbolicLinkType->Open = NULL;
147 IoSymbolicLinkType->Close = NULL;
148 IoSymbolicLinkType->Delete = NULL;
149 IoSymbolicLinkType->Parse = IopParseSymbolicLink;
150 IoSymbolicLinkType->Security = NULL;
151 IoSymbolicLinkType->QueryName = NULL;
152 IoSymbolicLinkType->OkayToClose = NULL;
153 IoSymbolicLinkType->Create = IopCreateSymbolicLink;
154
155 RtlInitAnsiString(
156 & AnsiString,
157 "Symbolic Link"
158 );
159 RtlAnsiStringToUnicodeString(
160 & IoSymbolicLinkType->TypeName,
161 & AnsiString,
162 TRUE
163 );
164 }
165
166
167 /**********************************************************************
168 * NAME EXPORTED
169 * NtOpenSymbolicLinkObject
170 *
171 * DESCRIPTION
172 *
173 * ARGUMENTS
174 *
175 * RETURN VALUE
176 *
177 * REVISIONS
178 *
179 */
180 NTSTATUS
181 STDCALL
182 NtOpenSymbolicLinkObject (
183 OUT PHANDLE LinkHandle,
184 IN ACCESS_MASK DesiredAccess,
185 IN POBJECT_ATTRIBUTES ObjectAttributes
186 )
187 {
188 NTSTATUS Status;
189 PVOID Object;
190
191 Status = ObReferenceObjectByName(
192 ObjectAttributes->ObjectName,
193 ObjectAttributes->Attributes,
194 NULL,
195 DesiredAccess,
196 NULL,
197 UserMode,
198 NULL,
199 & Object
200 );
201 if (!NT_SUCCESS(Status))
202 {
203 return Status;
204 }
205
206 Status = ObCreateHandle(
207 PsGetCurrentProcess(),
208 Object,
209 DesiredAccess,
210 FALSE,
211 LinkHandle
212 );
213 if (!NT_SUCCESS(Status))
214 {
215 return Status;
216 }
217
218 return STATUS_SUCCESS;
219 }
220
221
222 /**********************************************************************
223 * NAME EXPORTED
224 * NtQuerySymbolicLinkObject
225 *
226 * DESCRIPTION
227 *
228 * ARGUMENTS
229 *
230 * RETURN VALUE
231 *
232 * REVISIONS
233 *
234 */
235 NTSTATUS
236 STDCALL
237 NtQuerySymbolicLinkObject (
238 IN HANDLE LinkHandle,
239 IN OUT PUNICODE_STRING LinkTarget,
240 OUT PULONG ReturnedLength OPTIONAL
241 )
242 {
243 PSYMLNK_OBJECT SymlinkObject;
244 NTSTATUS Status;
245
246 Status = ObReferenceObjectByHandle(
247 LinkHandle,
248 SYMBOLIC_LINK_QUERY,
249 IoSymbolicLinkType,
250 UserMode,
251 (PVOID *) & SymlinkObject,
252 NULL
253 );
254 if (Status != STATUS_SUCCESS)
255 {
256 return Status;
257 }
258
259 RtlCopyUnicodeString(
260 LinkTarget,
261 SymlinkObject->Target.ObjectName
262 );
263 if (ReturnedLength != NULL)
264 {
265 *ReturnedLength = SymlinkObject->Target.Length;
266 }
267 ObDereferenceObject(SymlinkObject);
268
269 return STATUS_SUCCESS;
270 }
271
272
273 /**********************************************************************
274 * NAME EXPORTED
275 * IoCreateUnprotectedSymbolicLink
276 *
277 * DESCRIPTION
278 *
279 * ARGUMENTS
280 *
281 * RETURN VALUE
282 *
283 * REVISIONS
284 *
285 */
286 NTSTATUS
287 STDCALL
288 IoCreateUnprotectedSymbolicLink (
289 PUNICODE_STRING SymbolicLinkName,
290 PUNICODE_STRING DeviceName
291 )
292 {
293 return IoCreateSymbolicLink(
294 SymbolicLinkName,
295 DeviceName
296 );
297 }
298
299
300 /**********************************************************************
301 * NAME EXPORTED
302 * IoCreateSymbolicLink
303 *
304 * DESCRIPTION
305 *
306 * ARGUMENTS
307 *
308 * RETURN VALUE
309 *
310 * REVISIONS
311 *
312 */
313 NTSTATUS
314 STDCALL
315 IoCreateSymbolicLink (
316 PUNICODE_STRING SymbolicLinkName,
317 PUNICODE_STRING DeviceName
318 )
319 {
320 OBJECT_ATTRIBUTES ObjectAttributes;
321 HANDLE SymbolicLinkHandle;
322 PSYMLNK_OBJECT SymbolicLink;
323
324 assert_irql(PASSIVE_LEVEL);
325
326 DPRINT(
327 "IoCreateSymbolicLink(SymbolicLinkName %w, DeviceName %w)\n",
328 SymbolicLinkName->Buffer,
329 DeviceName->Buffer
330 );
331
332 InitializeObjectAttributes(
333 & ObjectAttributes,
334 SymbolicLinkName,
335 0,
336 NULL,
337 NULL
338 );
339 SymbolicLink = ObCreateObject(
340 & SymbolicLinkHandle,
341 SYMBOLIC_LINK_ALL_ACCESS,
342 & ObjectAttributes,
343 IoSymbolicLinkType
344 );
345 if (SymbolicLink == NULL)
346 {
347 return STATUS_UNSUCCESSFUL;
348 }
349
350 ZwClose(SymbolicLinkHandle);
351
352 SymbolicLink->TargetName.Length = 0;
353 SymbolicLink->TargetName.MaximumLength =
354 ((wcslen(DeviceName->Buffer) + 1) * sizeof(WCHAR));
355 SymbolicLink->TargetName.Buffer =
356 ExAllocatePool(
357 NonPagedPool,
358 SymbolicLink->TargetName.MaximumLength
359 );
360 RtlCopyUnicodeString(
361 & (SymbolicLink->TargetName),
362 DeviceName
363 );
364
365 DPRINT("DeviceName %w\n", SymbolicLink->TargetName.Buffer);
366
367 InitializeObjectAttributes(
368 & (SymbolicLink->Target),
369 & (SymbolicLink->TargetName),
370 0,
371 NULL,
372 NULL
373 );
374
375 DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__);
376
377 return STATUS_SUCCESS;
378 }
379
380
381 /**********************************************************************
382 * NAME EXPORTED
383 * IoDeleteSymbolicLink
384 *
385 * DESCRIPTION
386 *
387 * ARGUMENTS
388 *
389 * RETURN VALUE
390 *
391 * REVISIONS
392 *
393 */
394 NTSTATUS
395 STDCALL
396 IoDeleteSymbolicLink (
397 PUNICODE_STRING DeviceName
398 )
399 {
400 UNIMPLEMENTED;
401 }
402
403
404 /**********************************************************************
405 * NAME (EXPORTED as Zw)
406 * NtCreateSymbolicLinkObject
407 *
408 * DESCRIPTION
409 *
410 * ARGUMENTS
411 *
412 * RETURN VALUE
413 *
414 * REVISIONS
415 *
416 */
417 NTSTATUS
418 STDCALL
419 NtCreateSymbolicLinkObject (
420 OUT PHANDLE SymbolicLinkHandle,
421 IN ACCESS_MASK DesiredAccess,
422 IN POBJECT_ATTRIBUTES ObjectAttributes,
423 IN PUNICODE_STRING Name
424 )
425 {
426 UNIMPLEMENTED;
427 }
428
429
430 /* EOF */