| |
| |
| |
| |
| |
| |
| #include <psxtypes/psxtypes.h> |
| #include <ntapi/nt_object.h> |
| #include <ntapi/nt_guid.h> |
| #include <ntapi/nt_string.h> |
| #include <ntapi/nt_acl.h> |
| #include "ntapi_impl.h" |
| |
| #define __SID_SYSTEM {1,1,{{0,0,0,0,0,5}},{18}} |
| #define __SID_OWNER_RIGHTS {1,1,{{0,0,0,0,0,3}},{4}} |
| #define __SID_AUTHENTICATED_USERS {1,1,{{0,0,0,0,0,5}},{11}} |
| |
| static const nt_sid sid_system = __SID_SYSTEM; |
| static const nt_sid sid_owner_rights = __SID_OWNER_RIGHTS; |
| static const nt_sid sid_auth_users = __SID_AUTHENTICATED_USERS; |
| |
| typedef ntapi_zw_open_directory_object objdir_open_fn; |
| |
| static void __tt_guid_to_hex_utf16( |
| __in const nt_guid * guid, |
| __out wchar16_t * hex_str) |
| { |
| uint16_t key; |
| |
| __ntapi_tt_uint32_to_hex_utf16( |
| guid->data1,&hex_str[0]); |
| |
| __ntapi_tt_uint16_to_hex_utf16( |
| guid->data2,&hex_str[9]); |
| |
| __ntapi_tt_uint16_to_hex_utf16( |
| guid->data3,&hex_str[14]); |
| |
| key = guid->data4[0] * 0x100 + guid->data4[1]; |
| |
| __ntapi_tt_uint16_to_hex_utf16( |
| key,&hex_str[19]); |
| |
| key = guid->data4[2] * 0x100 + guid->data4[3]; |
| |
| __ntapi_tt_uint16_to_hex_utf16( |
| key,&hex_str[24]); |
| |
| key = guid->data4[4] * 0x100 + guid->data4[5]; |
| |
| __ntapi_tt_uint16_to_hex_utf16( |
| key,&hex_str[28]); |
| |
| key = guid->data4[6] * 0x100 + guid->data4[7]; |
| |
| __ntapi_tt_uint16_to_hex_utf16( |
| key,&hex_str[32]); |
| |
| hex_str[8] = '-'; |
| hex_str[13] = '-'; |
| hex_str[18] = '-'; |
| hex_str[23] = '-'; |
| } |
| |
| static nt_access_allowed_ace * __ipc_ace_init( |
| nt_access_allowed_ace * ace, |
| uint32_t mask, |
| const nt_sid * sid) |
| { |
| ace->mask = mask; |
| ace->header.ace_type = NT_ACE_TYPE_ACCESS_ALLOWED; |
| ace->header.ace_flags = 0; |
| ace->header.ace_size = sizeof(uint32_t) * sid->sub_authority_count |
| + __offsetof(nt_access_allowed_ace,sid_start) |
| + __offsetof(nt_sid,sub_authority); |
| |
| __ntapi->tt_sid_copy( |
| (nt_sid *)&ace->sid_start, |
| sid); |
| |
| return (nt_access_allowed_ace *)((size_t)ace + ace->header.ace_size); |
| } |
| |
| static void __ipc_sd_init(nt_sd_common_buffer * sd, int fdir) |
| { |
| nt_access_allowed_ace * ace; |
| uint32_t mask_system; |
| uint32_t mask_owner; |
| uint32_t mask_other; |
| |
| |
| if (fdir) { |
| mask_system = NT_SEC_READ_CONTROL |
| | NT_DIRECTORY_QUERY |
| | NT_DIRECTORY_TRAVERSE |
| | NT_DIRECTORY_CREATE_OBJECT |
| | NT_DIRECTORY_CREATE_SUBDIRECTORY; |
| |
| mask_owner = NT_DIRECTORY_ALL_ACCESS; |
| mask_other = mask_system; |
| } else { |
| mask_system = NT_SYMBOLIC_LINK_ALL_ACCESS; |
| mask_owner = NT_SYMBOLIC_LINK_ALL_ACCESS; |
| mask_other = NT_SYMBOLIC_LINK_ALL_ACCESS; |
| } |
| |
| |
| sd->sd.revision = 1; |
| sd->sd.sbz_1st = 0; |
| sd->sd.control = NT_SE_SELF_RELATIVE | NT_SE_DACL_PRESENT; |
| sd->sd.offset_owner = __offsetof(nt_sd_common_buffer,owner); |
| sd->sd.offset_group = 0; |
| sd->sd.offset_dacl = __offsetof(nt_sd_common_buffer,dacl); |
| sd->sd.offset_sacl = 0; |
| |
| |
| __ntapi->tt_sid_copy( |
| (nt_sid *)&sd->owner, |
| __ntapi_internals()->user); |
| |
| |
| |
| ace = (nt_access_allowed_ace *)&sd->buffer; |
| ace = __ipc_ace_init(ace,mask_system,&sid_system); |
| ace = __ipc_ace_init(ace,mask_other,&sid_auth_users); |
| ace = __ipc_ace_init(ace,mask_owner,&sid_owner_rights); |
| ace = __ipc_ace_init(ace,mask_owner,(nt_sid *)&sd->owner); |
| |
| sd->dacl.acl_revision = 0x02; |
| sd->dacl.sbz_1st = 0; |
| sd->dacl.acl_size = (uint16_t)((char *)ace - (char *)&sd->dacl); |
| sd->dacl.ace_count = 3; |
| sd->dacl.sbz_2nd = 0; |
| |
| } |
| |
| static int32_t __stdcall __tt_create_ipc_object_directory( |
| __out void ** hdir, |
| __in uint32_t desired_access, |
| __in const wchar16_t prefix[6], |
| __in const nt_guid * guid) |
| { |
| int32_t status; |
| nt_ipc_objdir_name objdir_name; |
| nt_unicode_string name; |
| nt_sd_common_buffer sd; |
| nt_oa oa; |
| nt_sqos sqos = { |
| sizeof(sqos), |
| NT_SECURITY_IMPERSONATION, |
| NT_SECURITY_TRACKING_DYNAMIC, |
| 1}; |
| |
| __ipc_sd_init(&sd,1); |
| |
| __ntapi->tt_generic_memcpy( |
| objdir_name.base_named_objects, |
| (wchar16_t[])__NT_BASED_NAMED_OBJECTS, |
| sizeof(objdir_name.base_named_objects)); |
| |
| __ntapi->tt_memcpy_utf16( |
| objdir_name.prefix, |
| prefix, |
| sizeof(objdir_name.prefix)); |
| |
| __tt_guid_to_hex_utf16( |
| guid,objdir_name.guid); |
| |
| objdir_name.backslash = '\\'; |
| objdir_name.uscore = '_'; |
| |
| name.strlen = sizeof(objdir_name); |
| name.maxlen = 0; |
| name.buffer = objdir_name.base_named_objects; |
| |
| oa.len = sizeof(oa); |
| oa.root_dir = 0; |
| oa.obj_name = &name; |
| oa.obj_attr = NT_OBJ_INHERIT |
| | NT_OBJ_OPENIF |
| | NT_OBJ_CASE_INSENSITIVE; |
| oa.sec_desc = &sd.sd; |
| oa.sec_qos = &sqos; |
| |
| status = __ntapi->zw_create_directory_object( |
| hdir,desired_access,&oa); |
| |
| return (status == NT_STATUS_OBJECT_NAME_EXISTS) |
| ? NT_STATUS_SUCCESS |
| : status; |
| } |
| |
| |
| static int32_t __stdcall __tt_create_keyed_object_directory( |
| __out void ** hdir, |
| __in uint32_t desired_access, |
| __in void * hparent, |
| __in uint32_t key, |
| __in objdir_open_fn * openfn) |
| { |
| wchar16_t keystr[8]; |
| nt_unicode_string name; |
| nt_sd_common_buffer sd; |
| nt_oa oa; |
| nt_sqos sqos = { |
| sizeof(sqos), |
| NT_SECURITY_IMPERSONATION, |
| NT_SECURITY_TRACKING_DYNAMIC, |
| 1}; |
| |
| __ipc_sd_init(&sd,1); |
| |
| __ntapi->tt_uint32_to_hex_utf16( |
| key,keystr); |
| |
| name.strlen = sizeof(keystr); |
| name.maxlen = 0; |
| name.buffer = keystr; |
| |
| oa.len = sizeof(oa); |
| oa.root_dir = hparent; |
| oa.obj_name = &name; |
| oa.obj_attr = NT_OBJ_INHERIT; |
| oa.sec_desc = &sd.sd; |
| oa.sec_qos = &sqos; |
| |
| return openfn(hdir,desired_access,&oa); |
| } |
| |
| |
| static int32_t __stdcall __tt_create_object_directory_entry( |
| __out void ** hentry, |
| __in uint32_t desired_access, |
| __in void * hdir, |
| __in void * htarget, |
| __in nt_unicode_string * target_name, |
| __in uint32_t key) |
| { |
| int32_t status; |
| nt_oa oa; |
| nt_unicode_string name; |
| nt_sd_common_buffer sd; |
| wchar16_t keystr[8]; |
| uintptr_t buffer[2048/sizeof(uintptr_t)]; |
| nt_sqos sqos = { |
| sizeof(sqos), |
| NT_SECURITY_IMPERSONATION, |
| NT_SECURITY_TRACKING_DYNAMIC, |
| 1}; |
| |
| if (!target_name) { |
| if ((status = __ntapi->zw_query_object( |
| htarget, |
| NT_OBJECT_NAME_INFORMATION, |
| buffer,sizeof(buffer),0))) |
| return status; |
| target_name = (nt_unicode_string *)buffer; |
| } |
| |
| __ipc_sd_init(&sd,0); |
| __ntapi->tt_uint32_to_hex_utf16(key,keystr); |
| |
| name.strlen = sizeof(keystr); |
| name.maxlen = 0; |
| name.buffer = keystr; |
| |
| oa.len = sizeof(oa); |
| oa.root_dir = hdir; |
| oa.obj_name = &name; |
| oa.obj_attr = 0; |
| oa.sec_desc = &sd.sd; |
| oa.sec_qos = &sqos; |
| |
| return __ntapi->zw_create_symbolic_link_object( |
| hentry, |
| desired_access, |
| &oa,target_name); |
| } |
| |
| int32_t __stdcall __ntapi_tt_open_ipc_object_directory( |
| __out void ** hdir, |
| __in uint32_t desired_access, |
| __in const wchar16_t prefix[6], |
| __in const nt_guid * guid) |
| { |
| return __tt_create_ipc_object_directory( |
| hdir,desired_access, |
| prefix,guid); |
| } |
| |
| int32_t __stdcall __ntapi_tt_create_ipc_object_directory_entry( |
| __out void ** hentry, |
| __in uint32_t desired_access, |
| __in void * hdir, |
| __in void * htarget, |
| __in nt_unicode_string * target_name, |
| __in uint32_t key) |
| { |
| return __tt_create_object_directory_entry( |
| hentry,desired_access, |
| hdir,htarget,target_name,key); |
| } |
| |
| int32_t __stdcall __ntapi_tt_open_dev_object_directory( |
| __out void ** hdir, |
| __in uint32_t desired_access, |
| __in const wchar16_t prefix[6], |
| __in const nt_guid * ipc_guid) |
| { |
| return __tt_create_ipc_object_directory( |
| hdir,desired_access, |
| prefix,ipc_guid); |
| } |
| |
| int32_t __stdcall __ntapi_tt_create_dev_object_directory_entry( |
| __out void ** hentry, |
| __in uint32_t desired_access, |
| __in void * hdir, |
| __in void * htarget, |
| __in nt_unicode_string * target_name, |
| __in const nt_guid * dev_guid) |
| { |
| int32_t status; |
| nt_oa oa; |
| nt_unicode_string name; |
| nt_sd_common_buffer sd; |
| nt_guid_str_utf16 guidstr; |
| uintptr_t buffer[2048/sizeof(uintptr_t)]; |
| nt_sqos sqos = { |
| sizeof(sqos), |
| NT_SECURITY_IMPERSONATION, |
| NT_SECURITY_TRACKING_DYNAMIC, |
| 1}; |
| |
| if (!target_name) { |
| if ((status = __ntapi->zw_query_object( |
| htarget, |
| NT_OBJECT_NAME_INFORMATION, |
| buffer,sizeof(buffer),0))) |
| return status; |
| target_name = (nt_unicode_string *)buffer; |
| } |
| |
| __ipc_sd_init(&sd,0); |
| __ntapi->tt_guid_to_string_utf16(dev_guid,&guidstr); |
| |
| name.strlen = sizeof(guidstr); |
| name.maxlen = 0; |
| name.buffer = &guidstr.lbrace; |
| |
| oa.len = sizeof(oa); |
| oa.root_dir = hdir; |
| oa.obj_name = &name; |
| oa.obj_attr = 0; |
| oa.sec_desc = &sd.sd; |
| oa.sec_qos = &sqos; |
| |
| return __ntapi->zw_create_symbolic_link_object( |
| hentry, |
| desired_access, |
| &oa,target_name); |
| } |
| |
| int32_t __stdcall __ntapi_tt_create_keyed_object_directory( |
| __out void ** hdir, |
| __in uint32_t desired_access, |
| __in void * hparent, |
| __in uint32_t key) |
| { |
| return __tt_create_keyed_object_directory( |
| hdir,desired_access, |
| hparent,key, |
| __ntapi->zw_create_directory_object); |
| } |
| |
| int32_t __stdcall __ntapi_tt_open_keyed_object_directory( |
| __out void ** hdir, |
| __in uint32_t desired_access, |
| __in void * hparent, |
| __in uint32_t key) |
| { |
| return __tt_create_keyed_object_directory( |
| hdir,desired_access, |
| hparent,key, |
| __ntapi->zw_open_directory_object); |
| } |
| |
| int32_t __stdcall __ntapi_tt_create_keyed_object_directory_entry( |
| __out void ** hentry, |
| __in uint32_t desired_access, |
| __in void * hdir, |
| __in void * htarget, |
| __in nt_unicode_string * target_name, |
| __in uint32_t key) |
| { |
| return __tt_create_object_directory_entry( |
| hentry,desired_access, |
| hdir,htarget,target_name,key); |
| } |
| |
| int32_t __stdcall __ntapi_tt_keyed_object_to_key( |
| __in void * hentry, |
| __out uint32_t * key, |
| __out void * buffer, |
| __in size_t buflen) |
| { |
| int32_t status; |
| wchar16_t * pidname; |
| nt_unicode_string * dirname; |
| |
| if ((status = __ntapi->zw_query_object( |
| hentry, |
| NT_OBJECT_NAME_INFORMATION, |
| buffer,buflen, |
| &(uint32_t){0}))) |
| return status; |
| |
| dirname = (nt_unicode_string *)buffer; |
| pidname = dirname->buffer; |
| |
| if (dirname->strlen <= 8 * sizeof(wchar16_t)) |
| return NT_STATUS_INTERNAL_ERROR; |
| |
| pidname += dirname->strlen / sizeof(wchar16_t); |
| pidname -= 8; |
| |
| if (pidname[-1] != '\\') |
| return NT_STATUS_INVALID_PARAMETER; |
| |
| return __ntapi->tt_hex_utf16_to_uint32( |
| pidname,key); |
| } |