Implement directory object in wineserver.
Implement Nt[Create|Open]DirectoryObject. Change tests accordingly.
This commit is contained in:
parent
4cbf118d88
commit
3c6bdcce53
@ -362,30 +362,77 @@ NTSTATUS WINAPI NtClose( HANDLE Handle )
|
|||||||
* Success: ERROR_SUCCESS.
|
* Success: ERROR_SUCCESS.
|
||||||
* Failure: An NTSTATUS error code.
|
* Failure: An NTSTATUS error code.
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI NtOpenDirectoryObject(
|
NTSTATUS WINAPI NtOpenDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
|
||||||
PHANDLE DirectoryHandle,
|
POBJECT_ATTRIBUTES ObjectAttributes)
|
||||||
ACCESS_MASK DesiredAccess,
|
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes)
|
|
||||||
{
|
{
|
||||||
FIXME("(%p,0x%08lx,%p): stub\n",
|
NTSTATUS ret;
|
||||||
DirectoryHandle, DesiredAccess, ObjectAttributes);
|
TRACE("(%p,0x%08lx)\n", DirectoryHandle, DesiredAccess);
|
||||||
dump_ObjectAttributes(ObjectAttributes);
|
dump_ObjectAttributes(ObjectAttributes);
|
||||||
return 0;
|
|
||||||
|
if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
|
||||||
|
if (!ObjectAttributes) return STATUS_INVALID_PARAMETER;
|
||||||
|
/* Have to test it here because server won't know difference between
|
||||||
|
* ObjectName == NULL and ObjectName == "" */
|
||||||
|
if (!ObjectAttributes->ObjectName)
|
||||||
|
{
|
||||||
|
if (ObjectAttributes->RootDirectory)
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
else
|
||||||
|
return STATUS_OBJECT_PATH_SYNTAX_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
SERVER_START_REQ(open_directory)
|
||||||
|
{
|
||||||
|
req->access = DesiredAccess;
|
||||||
|
req->attributes = ObjectAttributes->Attributes;
|
||||||
|
req->rootdir = ObjectAttributes->RootDirectory;
|
||||||
|
if (ObjectAttributes->ObjectName)
|
||||||
|
wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
|
||||||
|
ObjectAttributes->ObjectName->Length);
|
||||||
|
ret = wine_server_call( req );
|
||||||
|
*DirectoryHandle = reply->handle;
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* NtCreateDirectoryObject [NTDLL.@]
|
* NtCreateDirectoryObject [NTDLL.@]
|
||||||
* ZwCreateDirectoryObject [NTDLL.@]
|
* ZwCreateDirectoryObject [NTDLL.@]
|
||||||
|
*
|
||||||
|
* Create a namespace directory object.
|
||||||
|
*
|
||||||
|
* PARAMS
|
||||||
|
* DirectoryHandle [O] Destination for the new directory handle
|
||||||
|
* DesiredAccess [I] Desired access to the directory
|
||||||
|
* ObjectAttributes [I] Structure describing the directory
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* Success: ERROR_SUCCESS.
|
||||||
|
* Failure: An NTSTATUS error code.
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI NtCreateDirectoryObject(
|
NTSTATUS WINAPI NtCreateDirectoryObject(PHANDLE DirectoryHandle, ACCESS_MASK DesiredAccess,
|
||||||
PHANDLE DirectoryHandle,
|
POBJECT_ATTRIBUTES ObjectAttributes)
|
||||||
ACCESS_MASK DesiredAccess,
|
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes)
|
|
||||||
{
|
{
|
||||||
FIXME("(%p,0x%08lx,%p),stub!\n",
|
NTSTATUS ret;
|
||||||
DirectoryHandle,DesiredAccess,ObjectAttributes);
|
TRACE("(%p,0x%08lx)\n", DirectoryHandle, DesiredAccess);
|
||||||
dump_ObjectAttributes(ObjectAttributes);
|
dump_ObjectAttributes(ObjectAttributes);
|
||||||
return 0;
|
|
||||||
|
if (!DirectoryHandle) return STATUS_ACCESS_VIOLATION;
|
||||||
|
|
||||||
|
SERVER_START_REQ(create_directory)
|
||||||
|
{
|
||||||
|
req->access = DesiredAccess;
|
||||||
|
req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
|
||||||
|
req->rootdir = ObjectAttributes ? ObjectAttributes->RootDirectory : 0;
|
||||||
|
if (ObjectAttributes && ObjectAttributes->ObjectName)
|
||||||
|
wine_server_add_data(req, ObjectAttributes->ObjectName->Buffer,
|
||||||
|
ObjectAttributes->ObjectName->Length);
|
||||||
|
ret = wine_server_call( req );
|
||||||
|
*DirectoryHandle = reply->handle;
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -186,11 +186,11 @@ static void test_name_collisions(void)
|
|||||||
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||||
pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
|
pRtlCreateUnicodeStringFromAsciiz(&str, "\\");
|
||||||
h = 0;
|
h = 0;
|
||||||
todo_wine{ DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION) }
|
DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_COLLISION)
|
||||||
ok(h == 0, "Failed create returned valid handle! (%p)\n", h);
|
ok(h == 0, "Failed create returned valid handle! (%p)\n", h);
|
||||||
InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
|
InitializeObjectAttributes(&attr, &str, OBJ_OPENIF, 0, NULL);
|
||||||
|
|
||||||
todo_wine{ DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS) }
|
DIR_TEST_CREATE_FAILURE(&h, STATUS_OBJECT_NAME_EXISTS)
|
||||||
pNtClose(h);
|
pNtClose(h);
|
||||||
status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
|
status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
|
||||||
todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
|
todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
|
||||||
@ -199,7 +199,7 @@ static void test_name_collisions(void)
|
|||||||
|
|
||||||
pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant");
|
pRtlCreateUnicodeStringFromAsciiz(&str, "\\??\\PIPE\\om.c-mutant");
|
||||||
status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
|
status = pNtCreateMutant(&h, GENERIC_ALL, &attr, FALSE);
|
||||||
todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH,
|
todo_wine ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_OBJECT_PATH_NOT_FOUND,
|
||||||
"NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
|
"NtCreateMutant should have failed with STATUS_OBJECT_TYPE_MISMATCH got(%08lx)\n", status);
|
||||||
pRtlFreeUnicodeString(&str);
|
pRtlFreeUnicodeString(&str);
|
||||||
|
|
||||||
@ -289,22 +289,22 @@ void test_directory(void)
|
|||||||
|
|
||||||
/* No name and/or no attributes */
|
/* No name and/or no attributes */
|
||||||
status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
|
status = pNtCreateDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
|
||||||
todo_wine ok(status == STATUS_ACCESS_VIOLATION,
|
ok(status == STATUS_ACCESS_VIOLATION,
|
||||||
"NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status);
|
"NtCreateDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status);
|
||||||
status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
|
status = pNtOpenDirectoryObject(NULL, DIRECTORY_QUERY, &attr);
|
||||||
todo_wine ok(status == STATUS_ACCESS_VIOLATION,
|
ok(status == STATUS_ACCESS_VIOLATION,
|
||||||
"NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status);
|
"NtOpenDirectoryObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)\n", status);
|
||||||
|
|
||||||
status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
|
status = pNtCreateDirectoryObject(&h, DIRECTORY_QUERY, NULL);
|
||||||
ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08lx)\n", status);
|
ok(status == STATUS_SUCCESS, "Failed to create Directory without attributes(%08lx)\n", status);
|
||||||
pNtClose(h);
|
pNtClose(h);
|
||||||
status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
|
status = pNtOpenDirectoryObject(&h, DIRECTORY_QUERY, NULL);
|
||||||
todo_wine ok(status == STATUS_INVALID_PARAMETER,
|
ok(status == STATUS_INVALID_PARAMETER,
|
||||||
"NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status);
|
"NtOpenDirectoryObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)\n", status);
|
||||||
|
|
||||||
InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
|
InitializeObjectAttributes(&attr, NULL, 0, 0, NULL);
|
||||||
DIR_TEST_CREATE_SUCCESS(&dir)
|
DIR_TEST_CREATE_SUCCESS(&dir)
|
||||||
todo_wine{ DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) }
|
DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
|
||||||
|
|
||||||
/* Bad name */
|
/* Bad name */
|
||||||
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||||
@ -312,15 +312,15 @@ void test_directory(void)
|
|||||||
pRtlCreateUnicodeStringFromAsciiz(&str, "");
|
pRtlCreateUnicodeStringFromAsciiz(&str, "");
|
||||||
DIR_TEST_CREATE_SUCCESS(&h)
|
DIR_TEST_CREATE_SUCCESS(&h)
|
||||||
pNtClose(h);
|
pNtClose(h);
|
||||||
todo_wine{ DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) }
|
DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
|
||||||
pRtlFreeUnicodeString(&str);
|
pRtlFreeUnicodeString(&str);
|
||||||
pNtClose(dir);
|
pNtClose(dir);
|
||||||
|
|
||||||
todo_wine{ DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD) }
|
DIR_TEST_CREATE_OPEN_FAILURE(&h, "BaseNamedObjects", STATUS_OBJECT_PATH_SYNTAX_BAD)
|
||||||
todo_wine{ DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID) }
|
DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\", STATUS_OBJECT_NAME_INVALID)
|
||||||
todo_wine{ DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID) }
|
DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\\\BaseNamedObjects", STATUS_OBJECT_NAME_INVALID)
|
||||||
todo_wine{ DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID) }
|
DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\\\om.c-test", STATUS_OBJECT_NAME_INVALID)
|
||||||
todo_wine{ DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND) }
|
DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\BaseNamedObjects\\om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
|
||||||
|
|
||||||
pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
|
pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\om.c-test");
|
||||||
DIR_TEST_CREATE_SUCCESS(&h)
|
DIR_TEST_CREATE_SUCCESS(&h)
|
||||||
@ -351,14 +351,14 @@ void test_directory(void)
|
|||||||
pRtlFreeUnicodeString(&str);
|
pRtlFreeUnicodeString(&str);
|
||||||
|
|
||||||
InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
|
InitializeObjectAttributes(&attr, NULL, 0, dir, NULL);
|
||||||
todo_wine{ DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID) }
|
DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_NAME_INVALID)
|
||||||
|
|
||||||
InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
|
InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
|
||||||
DIR_TEST_CREATE_OPEN_SUCCESS(&h, "")
|
DIR_TEST_CREATE_OPEN_SUCCESS(&h, "")
|
||||||
todo_wine{ DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD) }
|
DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
|
||||||
todo_wine{ DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD) }
|
DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test", STATUS_OBJECT_PATH_SYNTAX_BAD)
|
||||||
todo_wine{ DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD) }
|
DIR_TEST_CREATE_OPEN_FAILURE(&h, "\\om.c-test\\", STATUS_OBJECT_PATH_SYNTAX_BAD)
|
||||||
todo_wine{ DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND) }
|
DIR_TEST_CREATE_OPEN_FAILURE(&h, "om.c-test\\", STATUS_OBJECT_PATH_NOT_FOUND)
|
||||||
|
|
||||||
pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
|
pRtlCreateUnicodeStringFromAsciiz(&str, "om.c-test");
|
||||||
DIR_TEST_CREATE_SUCCESS(&dir1)
|
DIR_TEST_CREATE_SUCCESS(&dir1)
|
||||||
@ -374,7 +374,7 @@ void test_directory(void)
|
|||||||
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||||
DIR_TEST_OPEN_SUCCESS(&dir)
|
DIR_TEST_OPEN_SUCCESS(&dir)
|
||||||
InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
|
InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
|
||||||
todo_wine{ DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD) }
|
DIR_TEST_OPEN_FAILURE(&h, STATUS_OBJECT_PATH_SYNTAX_BAD)
|
||||||
pRtlFreeUnicodeString(&str);
|
pRtlFreeUnicodeString(&str);
|
||||||
pNtClose(dir);
|
pNtClose(dir);
|
||||||
|
|
||||||
@ -396,15 +396,15 @@ void test_directory(void)
|
|||||||
|
|
||||||
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||||
pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test");
|
pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Global\\om.c-test");
|
||||||
DIR_TEST_CREATE_SUCCESS(&dir)
|
todo_wine{ DIR_TEST_CREATE_SUCCESS(&dir) }
|
||||||
pRtlFreeUnicodeString(&str);
|
pRtlFreeUnicodeString(&str);
|
||||||
pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
|
pRtlCreateUnicodeStringFromAsciiz(&str, "\\BaseNamedObjects\\Local\\om.c-test\\one more level");
|
||||||
DIR_TEST_CREATE_SUCCESS(&h)
|
todo_wine{ DIR_TEST_CREATE_SUCCESS(&h) }
|
||||||
pRtlFreeUnicodeString(&str);
|
pRtlFreeUnicodeString(&str);
|
||||||
pNtClose(h);
|
pNtClose(h);
|
||||||
InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
|
InitializeObjectAttributes(&attr, &str, 0, dir, NULL);
|
||||||
pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
|
pRtlCreateUnicodeStringFromAsciiz(&str, "one more level");
|
||||||
DIR_TEST_CREATE_SUCCESS(&dir)
|
todo_wine{ DIR_TEST_CREATE_SUCCESS(&dir) }
|
||||||
pRtlFreeUnicodeString(&str);
|
pRtlFreeUnicodeString(&str);
|
||||||
pNtClose(h);
|
pNtClose(h);
|
||||||
|
|
||||||
|
@ -3577,6 +3577,38 @@ struct set_mailslot_info_reply
|
|||||||
#define MAILSLOT_SET_READ_TIMEOUT 1
|
#define MAILSLOT_SET_READ_TIMEOUT 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct create_directory_request
|
||||||
|
{
|
||||||
|
struct request_header __header;
|
||||||
|
unsigned int access;
|
||||||
|
unsigned int attributes;
|
||||||
|
obj_handle_t rootdir;
|
||||||
|
/* VARARG(directory_name,unicode_str); */
|
||||||
|
};
|
||||||
|
struct create_directory_reply
|
||||||
|
{
|
||||||
|
struct reply_header __header;
|
||||||
|
obj_handle_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct open_directory_request
|
||||||
|
{
|
||||||
|
struct request_header __header;
|
||||||
|
unsigned int access;
|
||||||
|
unsigned int attributes;
|
||||||
|
obj_handle_t rootdir;
|
||||||
|
/* VARARG(directory_name,unicode_str); */
|
||||||
|
};
|
||||||
|
struct open_directory_reply
|
||||||
|
{
|
||||||
|
struct reply_header __header;
|
||||||
|
obj_handle_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum request
|
enum request
|
||||||
{
|
{
|
||||||
REQ_new_process,
|
REQ_new_process,
|
||||||
@ -3784,6 +3816,8 @@ enum request
|
|||||||
REQ_create_mailslot,
|
REQ_create_mailslot,
|
||||||
REQ_open_mailslot,
|
REQ_open_mailslot,
|
||||||
REQ_set_mailslot_info,
|
REQ_set_mailslot_info,
|
||||||
|
REQ_create_directory,
|
||||||
|
REQ_open_directory,
|
||||||
REQ_NB_REQUESTS
|
REQ_NB_REQUESTS
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3996,6 +4030,8 @@ union generic_request
|
|||||||
struct create_mailslot_request create_mailslot_request;
|
struct create_mailslot_request create_mailslot_request;
|
||||||
struct open_mailslot_request open_mailslot_request;
|
struct open_mailslot_request open_mailslot_request;
|
||||||
struct set_mailslot_info_request set_mailslot_info_request;
|
struct set_mailslot_info_request set_mailslot_info_request;
|
||||||
|
struct create_directory_request create_directory_request;
|
||||||
|
struct open_directory_request open_directory_request;
|
||||||
};
|
};
|
||||||
union generic_reply
|
union generic_reply
|
||||||
{
|
{
|
||||||
@ -4206,8 +4242,10 @@ union generic_reply
|
|||||||
struct create_mailslot_reply create_mailslot_reply;
|
struct create_mailslot_reply create_mailslot_reply;
|
||||||
struct open_mailslot_reply open_mailslot_reply;
|
struct open_mailslot_reply open_mailslot_reply;
|
||||||
struct set_mailslot_info_reply set_mailslot_info_reply;
|
struct set_mailslot_info_reply set_mailslot_info_reply;
|
||||||
|
struct create_directory_reply create_directory_reply;
|
||||||
|
struct open_directory_reply open_directory_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 199
|
#define SERVER_PROTOCOL_VERSION 200
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
@ -17,6 +17,7 @@ C_SRCS = \
|
|||||||
context_sparc.c \
|
context_sparc.c \
|
||||||
context_x86_64.c \
|
context_x86_64.c \
|
||||||
debugger.c \
|
debugger.c \
|
||||||
|
directory.c \
|
||||||
event.c \
|
event.c \
|
||||||
fd.c \
|
fd.c \
|
||||||
file.c \
|
file.c \
|
||||||
|
354
server/directory.c
Normal file
354
server/directory.c
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
/*
|
||||||
|
* Server-side directory object management
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 Vitaliy Margolen
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "wine/port.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "ntstatus.h"
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
|
#include "winternl.h"
|
||||||
|
#include "ddk/wdm.h"
|
||||||
|
|
||||||
|
#include "handle.h"
|
||||||
|
#include "request.h"
|
||||||
|
#include "process.h"
|
||||||
|
#include "object.h"
|
||||||
|
#include "unicode.h"
|
||||||
|
|
||||||
|
#define HASH_SIZE 7 /* default hash size */
|
||||||
|
|
||||||
|
struct directory
|
||||||
|
{
|
||||||
|
struct object obj; /* object header */
|
||||||
|
struct namespace *entries; /* directory's name space */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void directory_dump( struct object *obj, int verbose );
|
||||||
|
static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name,
|
||||||
|
unsigned int attr );
|
||||||
|
static void directory_destroy( struct object *obj );
|
||||||
|
|
||||||
|
static const struct object_ops directory_ops =
|
||||||
|
{
|
||||||
|
sizeof(struct directory), /* size */
|
||||||
|
directory_dump, /* dump */
|
||||||
|
no_add_queue, /* add_queue */
|
||||||
|
NULL, /* remove_queue */
|
||||||
|
NULL, /* signaled */
|
||||||
|
NULL, /* satisfied */
|
||||||
|
no_signal, /* signal */
|
||||||
|
no_get_fd, /* get_fd */
|
||||||
|
directory_lookup_name, /* lookup_name */
|
||||||
|
no_close_handle, /* close_handle */
|
||||||
|
directory_destroy /* destroy */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct directory *root_directory;
|
||||||
|
|
||||||
|
|
||||||
|
static void directory_dump( struct object *obj, int verbose )
|
||||||
|
{
|
||||||
|
assert( obj->ops == &directory_ops );
|
||||||
|
|
||||||
|
fputs( "Directory ", stderr );
|
||||||
|
dump_object_name( obj );
|
||||||
|
fputc( '\n', stderr );
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct object *directory_lookup_name( struct object *obj, struct unicode_str *name,
|
||||||
|
unsigned int attr )
|
||||||
|
{
|
||||||
|
struct directory *dir = (struct directory *)obj;
|
||||||
|
struct object *found;
|
||||||
|
struct unicode_str tmp;
|
||||||
|
const WCHAR *p;
|
||||||
|
|
||||||
|
assert( obj->ops == &directory_ops );
|
||||||
|
|
||||||
|
if (!(p = memchrW( name->str, '\\', name->len / sizeof(WCHAR) )))
|
||||||
|
/* Last element in the path name */
|
||||||
|
tmp.len = name->len;
|
||||||
|
else
|
||||||
|
tmp.len = (p - name->str) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
tmp.str = name->str;
|
||||||
|
if ((found = find_object( dir->entries, &tmp, attr )))
|
||||||
|
{
|
||||||
|
/* Skip trailing \\ */
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
tmp.len += sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
/* Move to the next element*/
|
||||||
|
name->str = p;
|
||||||
|
name->len -= tmp.len;
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name->str)
|
||||||
|
{
|
||||||
|
if (tmp.len == 0) /* Double backslash */
|
||||||
|
set_error( STATUS_OBJECT_NAME_INVALID );
|
||||||
|
else if (p) /* Path still has backslashes */
|
||||||
|
set_error( STATUS_OBJECT_PATH_NOT_FOUND );
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void directory_destroy( struct object *obj )
|
||||||
|
{
|
||||||
|
struct directory *dir = (struct directory *)obj;
|
||||||
|
assert( obj->ops == &directory_ops );
|
||||||
|
free( dir->entries );
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct directory *create_directory( struct directory *root, const struct unicode_str *name,
|
||||||
|
unsigned int attr, unsigned int hash_size )
|
||||||
|
{
|
||||||
|
struct directory *dir;
|
||||||
|
|
||||||
|
if ((dir = create_named_object_dir( root, name, attr, &directory_ops )) &&
|
||||||
|
get_error() != STATUS_OBJECT_NAME_EXISTS)
|
||||||
|
{
|
||||||
|
if (!(dir->entries = create_namespace( hash_size )))
|
||||||
|
{
|
||||||
|
release_object( dir );
|
||||||
|
dir = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct directory *get_directory_obj( struct process *process, obj_handle_t handle, unsigned int access )
|
||||||
|
{
|
||||||
|
return (struct directory *)get_handle_obj( process, handle, access, &directory_ops );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Find an object by its name in a given root object
|
||||||
|
*
|
||||||
|
* PARAMS
|
||||||
|
* root [I] directory to start search from or NULL to start from \\
|
||||||
|
* name [I] object name to search for
|
||||||
|
* attr [I] OBJECT_ATTRIBUTES.Attributes
|
||||||
|
* name_left [O] [optional] leftover name if object is not found
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* NULL: If params are invalid
|
||||||
|
* Found: If object with exact name is found returns that object
|
||||||
|
* (name_left->len == 0). Object's refcount is incremented
|
||||||
|
* Not found: The last matched parent. (name_left->len > 0)
|
||||||
|
* Parent's refcount is incremented.
|
||||||
|
*/
|
||||||
|
struct object *find_object_dir( struct directory *root, const struct unicode_str *name,
|
||||||
|
unsigned int attr, struct unicode_str *name_left )
|
||||||
|
{
|
||||||
|
struct object *obj, *parent;
|
||||||
|
struct unicode_str name_tmp;
|
||||||
|
|
||||||
|
if (name) name_tmp = *name;
|
||||||
|
else name_tmp.len = 0;
|
||||||
|
|
||||||
|
/* Arguments check:
|
||||||
|
* - Either rootdir or name have to be specified
|
||||||
|
* - If root is specified path shouldn't start with backslash */
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
if (name_tmp.len && name_tmp.str[0] == '\\')
|
||||||
|
{
|
||||||
|
set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
parent = grab_object( root );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!name_tmp.len || name_tmp.str[0] != '\\')
|
||||||
|
{
|
||||||
|
set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
parent = grab_object( &root_directory->obj );
|
||||||
|
/* skip leading backslash */
|
||||||
|
name_tmp.str++;
|
||||||
|
name_tmp.len -= sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special case for opening RootDirectory */
|
||||||
|
if (!name_tmp.len) goto done;
|
||||||
|
|
||||||
|
while ((obj = parent->ops->lookup_name( parent, &name_tmp, attr )))
|
||||||
|
{
|
||||||
|
/* move to the next element */
|
||||||
|
release_object ( parent );
|
||||||
|
parent = obj;
|
||||||
|
}
|
||||||
|
if (get_error())
|
||||||
|
{
|
||||||
|
release_object( parent );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (name_left) *name_left = name_tmp;
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a named (if name is present) or unnamed object. */
|
||||||
|
void *create_named_object_dir( struct directory *root, const struct unicode_str *name,
|
||||||
|
unsigned int attributes, const struct object_ops *ops )
|
||||||
|
{
|
||||||
|
struct object *obj, *new_obj = NULL;
|
||||||
|
struct unicode_str new_name;
|
||||||
|
|
||||||
|
if (!name || !name->len) return alloc_object( ops );
|
||||||
|
|
||||||
|
if (!(obj = find_object_dir( root, name, attributes, &new_name ))) return NULL;
|
||||||
|
if (!new_name.len)
|
||||||
|
{
|
||||||
|
if (attributes & OBJ_OPENIF && obj->ops == ops)
|
||||||
|
set_error( STATUS_OBJECT_NAME_EXISTS );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
release_object( obj );
|
||||||
|
obj = NULL;
|
||||||
|
if (attributes & OBJ_OPENIF)
|
||||||
|
set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
||||||
|
else
|
||||||
|
set_error( STATUS_OBJECT_NAME_COLLISION );
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ATM we can't insert objects into anything else but directories */
|
||||||
|
if (obj->ops != &directory_ops)
|
||||||
|
set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct directory *dir = (struct directory *)obj;
|
||||||
|
if ((new_obj = create_object( dir->entries, ops, &new_name, &dir->obj )))
|
||||||
|
clear_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
release_object( obj );
|
||||||
|
return new_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open a new handle to an existing object */
|
||||||
|
obj_handle_t open_object_dir( struct directory *root, const struct unicode_str *name,
|
||||||
|
unsigned int attr, const struct object_ops *ops,
|
||||||
|
unsigned int access )
|
||||||
|
{
|
||||||
|
obj_handle_t handle = 0;
|
||||||
|
struct unicode_str name_left;
|
||||||
|
struct object *obj;
|
||||||
|
|
||||||
|
if ((obj = find_object_dir( root, name, attr, &name_left )))
|
||||||
|
{
|
||||||
|
if (name_left.len) /* not fully parsed */
|
||||||
|
set_error( STATUS_OBJECT_NAME_NOT_FOUND );
|
||||||
|
else if (ops && obj->ops != ops)
|
||||||
|
set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
||||||
|
else
|
||||||
|
handle = alloc_handle( current->process, obj, access, attr & OBJ_INHERIT );
|
||||||
|
|
||||||
|
release_object( obj );
|
||||||
|
}
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Global initialization */
|
||||||
|
|
||||||
|
static struct directory *dir_global, *dir_driver, *dir_device, *dir_basenamed;
|
||||||
|
|
||||||
|
void init_directories(void)
|
||||||
|
{
|
||||||
|
/* Directories */
|
||||||
|
static const WCHAR dir_globalW[] = {'?','?'};
|
||||||
|
static const WCHAR dir_driverW[] = {'D','r','i','v','e','r'};
|
||||||
|
static const WCHAR dir_deviceW[] = {'D','e','v','i','c','e'};
|
||||||
|
static const WCHAR dir_basenamedW[] = {'B','a','s','e','N','a','m','e','d','O','b','j','e','c','t','s'};
|
||||||
|
static const struct unicode_str dir_global_str = {dir_globalW, sizeof(dir_globalW)};
|
||||||
|
static const struct unicode_str dir_driver_str = {dir_driverW, sizeof(dir_driverW)};
|
||||||
|
static const struct unicode_str dir_device_str = {dir_deviceW, sizeof(dir_deviceW)};
|
||||||
|
static const struct unicode_str dir_basenamed_str = {dir_basenamedW, sizeof(dir_basenamedW)};
|
||||||
|
|
||||||
|
root_directory = create_directory( NULL, NULL, 0, HASH_SIZE );
|
||||||
|
dir_global = create_directory( root_directory, &dir_global_str, 0, HASH_SIZE );
|
||||||
|
dir_driver = create_directory( root_directory, &dir_driver_str, 0, HASH_SIZE );
|
||||||
|
dir_device = create_directory( root_directory, &dir_device_str, 0, HASH_SIZE );
|
||||||
|
/* use a larger hash table for this one since it can contain a lot of objects */
|
||||||
|
dir_basenamed = create_directory( root_directory, &dir_basenamed_str, 0, 37 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_directories(void)
|
||||||
|
{
|
||||||
|
release_object( dir_global );
|
||||||
|
release_object( dir_driver );
|
||||||
|
release_object( dir_device );
|
||||||
|
release_object( dir_basenamed );
|
||||||
|
release_object( root_directory );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* create a directory object */
|
||||||
|
DECL_HANDLER(create_directory)
|
||||||
|
{
|
||||||
|
struct unicode_str name;
|
||||||
|
struct directory *dir, *root = NULL;
|
||||||
|
|
||||||
|
reply->handle = 0;
|
||||||
|
get_req_unicode_str( &name );
|
||||||
|
if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((dir = create_directory( root, &name, req->attributes, HASH_SIZE )))
|
||||||
|
{
|
||||||
|
reply->handle = alloc_handle( current->process, dir, req->access,
|
||||||
|
req->attributes & OBJ_INHERIT );
|
||||||
|
release_object( dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root) release_object( root );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open a directory object */
|
||||||
|
DECL_HANDLER(open_directory)
|
||||||
|
{
|
||||||
|
struct unicode_str name;
|
||||||
|
struct directory *root = NULL;
|
||||||
|
|
||||||
|
get_req_unicode_str( &name );
|
||||||
|
if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
|
||||||
|
return;
|
||||||
|
|
||||||
|
reply->handle = open_object_dir( root, &name, req->attributes, &directory_ops, req->access );
|
||||||
|
|
||||||
|
if (root) release_object( root );
|
||||||
|
}
|
@ -135,6 +135,7 @@ int main( int argc, char *argv[] )
|
|||||||
|
|
||||||
if (debug_level) fprintf( stderr, "wineserver: starting (pid=%ld)\n", (long) getpid() );
|
if (debug_level) fprintf( stderr, "wineserver: starting (pid=%ld)\n", (long) getpid() );
|
||||||
init_signals();
|
init_signals();
|
||||||
|
init_directories();
|
||||||
init_registry();
|
init_registry();
|
||||||
main_loop();
|
main_loop();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -40,9 +40,10 @@
|
|||||||
|
|
||||||
struct object_name
|
struct object_name
|
||||||
{
|
{
|
||||||
struct list entry; /* entry in the hash list */
|
struct list entry; /* entry in the hash list */
|
||||||
struct object *obj;
|
struct object *obj; /* object owning this name */
|
||||||
size_t len;
|
struct object *parent; /* parent object */
|
||||||
|
size_t len; /* name length in bytes */
|
||||||
WCHAR name[1];
|
WCHAR name[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,6 +109,7 @@ static struct object_name *alloc_name( const struct unicode_str *name )
|
|||||||
if ((ptr = mem_alloc( sizeof(*ptr) + name->len - sizeof(ptr->name) )))
|
if ((ptr = mem_alloc( sizeof(*ptr) + name->len - sizeof(ptr->name) )))
|
||||||
{
|
{
|
||||||
ptr->len = name->len;
|
ptr->len = name->len;
|
||||||
|
ptr->parent = NULL;
|
||||||
memcpy( ptr->name, name->str, name->len );
|
memcpy( ptr->name, name->str, name->len );
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
@ -118,6 +120,7 @@ static void free_name( struct object *obj )
|
|||||||
{
|
{
|
||||||
struct object_name *ptr = obj->name;
|
struct object_name *ptr = obj->name;
|
||||||
list_remove( &ptr->entry );
|
list_remove( &ptr->entry );
|
||||||
|
if (ptr->parent) release_object( ptr->parent );
|
||||||
free( ptr );
|
free( ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,11 +162,27 @@ void *alloc_object( const struct object_ops *ops )
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *create_object( struct namespace *namespace, const struct object_ops *ops,
|
||||||
|
const struct unicode_str *name, struct object *parent )
|
||||||
|
{
|
||||||
|
struct object *obj;
|
||||||
|
struct object_name *name_ptr;
|
||||||
|
|
||||||
|
if (!(name_ptr = alloc_name( name ))) return NULL;
|
||||||
|
if ((obj = alloc_object( ops )))
|
||||||
|
{
|
||||||
|
set_object_name( namespace, obj, name_ptr );
|
||||||
|
if (parent) name_ptr->parent = grab_object( parent );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
free( name_ptr );
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
void *create_named_object( struct namespace *namespace, const struct object_ops *ops,
|
void *create_named_object( struct namespace *namespace, const struct object_ops *ops,
|
||||||
const struct unicode_str *name, unsigned int attributes )
|
const struct unicode_str *name, unsigned int attributes )
|
||||||
{
|
{
|
||||||
struct object *obj;
|
struct object *obj;
|
||||||
struct object_name *name_ptr;
|
|
||||||
|
|
||||||
if (!name || !name->len) return alloc_object( ops );
|
if (!name || !name->len) return alloc_object( ops );
|
||||||
|
|
||||||
@ -182,13 +201,7 @@ void *create_named_object( struct namespace *namespace, const struct object_ops
|
|||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
if (!(name_ptr = alloc_name( name ))) return NULL;
|
if ((obj = create_object( namespace, ops, name, NULL ))) clear_error();
|
||||||
if ((obj = alloc_object( ops )))
|
|
||||||
{
|
|
||||||
set_object_name( namespace, obj, name_ptr );
|
|
||||||
clear_error();
|
|
||||||
}
|
|
||||||
else free( name_ptr );
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ struct wait_queue_entry;
|
|||||||
struct async;
|
struct async;
|
||||||
struct async_queue;
|
struct async_queue;
|
||||||
struct winstation;
|
struct winstation;
|
||||||
|
struct directory;
|
||||||
|
|
||||||
|
|
||||||
struct unicode_str
|
struct unicode_str
|
||||||
@ -102,6 +103,8 @@ extern void *memdup( const void *data, size_t len );
|
|||||||
extern void *alloc_object( const struct object_ops *ops );
|
extern void *alloc_object( const struct object_ops *ops );
|
||||||
extern const WCHAR *get_object_name( struct object *obj, size_t *len );
|
extern const WCHAR *get_object_name( struct object *obj, size_t *len );
|
||||||
extern void dump_object_name( struct object *obj );
|
extern void dump_object_name( struct object *obj );
|
||||||
|
extern void *create_object( struct namespace *namespace, const struct object_ops *ops,
|
||||||
|
const struct unicode_str *name, struct object *parent );
|
||||||
extern void *create_named_object( struct namespace *namespace, const struct object_ops *ops,
|
extern void *create_named_object( struct namespace *namespace, const struct object_ops *ops,
|
||||||
const struct unicode_str *name, unsigned int attributes );
|
const struct unicode_str *name, unsigned int attributes );
|
||||||
extern struct namespace *create_namespace( unsigned int hash_size );
|
extern struct namespace *create_namespace( unsigned int hash_size );
|
||||||
@ -177,6 +180,19 @@ extern atom_t find_global_atom( struct winstation *winstation, const WCHAR *str,
|
|||||||
extern int grab_global_atom( struct winstation *winstation, atom_t atom );
|
extern int grab_global_atom( struct winstation *winstation, atom_t atom );
|
||||||
extern void release_global_atom( struct winstation *winstation, atom_t atom );
|
extern void release_global_atom( struct winstation *winstation, atom_t atom );
|
||||||
|
|
||||||
|
/* directory functions */
|
||||||
|
|
||||||
|
extern struct directory *get_directory_obj( struct process *process, obj_handle_t handle, unsigned int access );
|
||||||
|
extern struct object *find_object_dir( struct directory *root, const struct unicode_str *name,
|
||||||
|
unsigned int attr, struct unicode_str *name_left );
|
||||||
|
extern void *create_named_object_dir( struct directory *root, const struct unicode_str *name,
|
||||||
|
unsigned int attr, const struct object_ops *ops );
|
||||||
|
extern obj_handle_t open_object_dir( struct directory *root, const struct unicode_str *name,
|
||||||
|
unsigned int attr, const struct object_ops *ops,
|
||||||
|
unsigned int access );
|
||||||
|
extern void init_directories(void);
|
||||||
|
extern void close_directories(void);
|
||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
|
|
||||||
/* command-line options */
|
/* command-line options */
|
||||||
|
@ -2505,3 +2505,25 @@ enum message_type
|
|||||||
unsigned int next_msgsize;
|
unsigned int next_msgsize;
|
||||||
@END
|
@END
|
||||||
#define MAILSLOT_SET_READ_TIMEOUT 1
|
#define MAILSLOT_SET_READ_TIMEOUT 1
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a directory object */
|
||||||
|
@REQ(create_directory)
|
||||||
|
unsigned int access; /* access flags */
|
||||||
|
unsigned int attributes; /* object attributes */
|
||||||
|
obj_handle_t rootdir; /* root directory */
|
||||||
|
VARARG(directory_name,unicode_str); /* Directory name */
|
||||||
|
@REPLY
|
||||||
|
obj_handle_t handle; /* handle to the directory */
|
||||||
|
@END
|
||||||
|
|
||||||
|
|
||||||
|
/* Open a directory object */
|
||||||
|
@REQ(open_directory)
|
||||||
|
unsigned int access; /* access flags */
|
||||||
|
unsigned int attributes; /* object attributes */
|
||||||
|
obj_handle_t rootdir; /* root directory */
|
||||||
|
VARARG(directory_name,unicode_str); /* Directory name */
|
||||||
|
@REPLY
|
||||||
|
obj_handle_t handle; /* handle to the directory */
|
||||||
|
@END
|
||||||
|
@ -801,6 +801,7 @@ static void close_socket_timeout( void *arg )
|
|||||||
close_signals();
|
close_signals();
|
||||||
close_global_handles();
|
close_global_handles();
|
||||||
close_registry();
|
close_registry();
|
||||||
|
close_directories();
|
||||||
dump_objects(); /* dump any remaining objects */
|
dump_objects(); /* dump any remaining objects */
|
||||||
#else
|
#else
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -315,6 +315,8 @@ DECL_HANDLER(get_token_user);
|
|||||||
DECL_HANDLER(create_mailslot);
|
DECL_HANDLER(create_mailslot);
|
||||||
DECL_HANDLER(open_mailslot);
|
DECL_HANDLER(open_mailslot);
|
||||||
DECL_HANDLER(set_mailslot_info);
|
DECL_HANDLER(set_mailslot_info);
|
||||||
|
DECL_HANDLER(create_directory);
|
||||||
|
DECL_HANDLER(open_directory);
|
||||||
|
|
||||||
#ifdef WANT_REQUEST_HANDLERS
|
#ifdef WANT_REQUEST_HANDLERS
|
||||||
|
|
||||||
@ -526,6 +528,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||||||
(req_handler)req_create_mailslot,
|
(req_handler)req_create_mailslot,
|
||||||
(req_handler)req_open_mailslot,
|
(req_handler)req_open_mailslot,
|
||||||
(req_handler)req_set_mailslot_info,
|
(req_handler)req_set_mailslot_info,
|
||||||
|
(req_handler)req_create_directory,
|
||||||
|
(req_handler)req_open_directory,
|
||||||
};
|
};
|
||||||
#endif /* WANT_REQUEST_HANDLERS */
|
#endif /* WANT_REQUEST_HANDLERS */
|
||||||
|
|
||||||
|
@ -3093,6 +3093,34 @@ static void dump_set_mailslot_info_reply( const struct set_mailslot_info_reply *
|
|||||||
fprintf( stderr, " next_msgsize=%08x", req->next_msgsize );
|
fprintf( stderr, " next_msgsize=%08x", req->next_msgsize );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dump_create_directory_request( const struct create_directory_request *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " access=%08x,", req->access );
|
||||||
|
fprintf( stderr, " attributes=%08x,", req->attributes );
|
||||||
|
fprintf( stderr, " rootdir=%p,", req->rootdir );
|
||||||
|
fprintf( stderr, " directory_name=" );
|
||||||
|
dump_varargs_unicode_str( cur_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_create_directory_reply( const struct create_directory_reply *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " handle=%p", req->handle );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_open_directory_request( const struct open_directory_request *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " access=%08x,", req->access );
|
||||||
|
fprintf( stderr, " attributes=%08x,", req->attributes );
|
||||||
|
fprintf( stderr, " rootdir=%p,", req->rootdir );
|
||||||
|
fprintf( stderr, " directory_name=" );
|
||||||
|
dump_varargs_unicode_str( cur_size );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_open_directory_reply( const struct open_directory_reply *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " handle=%p", req->handle );
|
||||||
|
}
|
||||||
|
|
||||||
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(dump_func)dump_new_process_request,
|
(dump_func)dump_new_process_request,
|
||||||
(dump_func)dump_get_new_process_info_request,
|
(dump_func)dump_get_new_process_info_request,
|
||||||
@ -3299,6 +3327,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||||||
(dump_func)dump_create_mailslot_request,
|
(dump_func)dump_create_mailslot_request,
|
||||||
(dump_func)dump_open_mailslot_request,
|
(dump_func)dump_open_mailslot_request,
|
||||||
(dump_func)dump_set_mailslot_info_request,
|
(dump_func)dump_set_mailslot_info_request,
|
||||||
|
(dump_func)dump_create_directory_request,
|
||||||
|
(dump_func)dump_open_directory_request,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||||
@ -3507,6 +3537,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||||||
(dump_func)dump_create_mailslot_reply,
|
(dump_func)dump_create_mailslot_reply,
|
||||||
(dump_func)dump_open_mailslot_reply,
|
(dump_func)dump_open_mailslot_reply,
|
||||||
(dump_func)dump_set_mailslot_info_reply,
|
(dump_func)dump_set_mailslot_info_reply,
|
||||||
|
(dump_func)dump_create_directory_reply,
|
||||||
|
(dump_func)dump_open_directory_reply,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const req_names[REQ_NB_REQUESTS] = {
|
static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
@ -3715,6 +3747,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||||||
"create_mailslot",
|
"create_mailslot",
|
||||||
"open_mailslot",
|
"open_mailslot",
|
||||||
"set_mailslot_info",
|
"set_mailslot_info",
|
||||||
|
"create_directory",
|
||||||
|
"open_directory",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct
|
static const struct
|
||||||
@ -3752,6 +3786,7 @@ static const struct
|
|||||||
{ "KEY_DELETED", STATUS_KEY_DELETED },
|
{ "KEY_DELETED", STATUS_KEY_DELETED },
|
||||||
{ "MEDIA_WRITE_PROTECTED", STATUS_MEDIA_WRITE_PROTECTED },
|
{ "MEDIA_WRITE_PROTECTED", STATUS_MEDIA_WRITE_PROTECTED },
|
||||||
{ "MUTANT_NOT_OWNED", STATUS_MUTANT_NOT_OWNED },
|
{ "MUTANT_NOT_OWNED", STATUS_MUTANT_NOT_OWNED },
|
||||||
|
{ "NAME_TOO_LONG", STATUS_NAME_TOO_LONG },
|
||||||
{ "NOT_ALL_ASSIGNED", STATUS_NOT_ALL_ASSIGNED },
|
{ "NOT_ALL_ASSIGNED", STATUS_NOT_ALL_ASSIGNED },
|
||||||
{ "NOT_A_DIRECTORY", STATUS_NOT_A_DIRECTORY },
|
{ "NOT_A_DIRECTORY", STATUS_NOT_A_DIRECTORY },
|
||||||
{ "NOT_IMPLEMENTED", STATUS_NOT_IMPLEMENTED },
|
{ "NOT_IMPLEMENTED", STATUS_NOT_IMPLEMENTED },
|
||||||
@ -3769,6 +3804,8 @@ static const struct
|
|||||||
{ "OBJECT_NAME_INVALID", STATUS_OBJECT_NAME_INVALID },
|
{ "OBJECT_NAME_INVALID", STATUS_OBJECT_NAME_INVALID },
|
||||||
{ "OBJECT_NAME_NOT_FOUND", STATUS_OBJECT_NAME_NOT_FOUND },
|
{ "OBJECT_NAME_NOT_FOUND", STATUS_OBJECT_NAME_NOT_FOUND },
|
||||||
{ "OBJECT_PATH_INVALID", STATUS_OBJECT_PATH_INVALID },
|
{ "OBJECT_PATH_INVALID", STATUS_OBJECT_PATH_INVALID },
|
||||||
|
{ "OBJECT_PATH_NOT_FOUND", STATUS_OBJECT_PATH_NOT_FOUND },
|
||||||
|
{ "OBJECT_PATH_SYNTAX_BAD", STATUS_OBJECT_PATH_SYNTAX_BAD },
|
||||||
{ "OBJECT_TYPE_MISMATCH", STATUS_OBJECT_TYPE_MISMATCH },
|
{ "OBJECT_TYPE_MISMATCH", STATUS_OBJECT_TYPE_MISMATCH },
|
||||||
{ "PENDING", STATUS_PENDING },
|
{ "PENDING", STATUS_PENDING },
|
||||||
{ "PIPE_BUSY", STATUS_PIPE_BUSY },
|
{ "PIPE_BUSY", STATUS_PIPE_BUSY },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user