Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbase_x.h
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS System Libraries 00004 * FILE: dll/win32/kernel32/include/base_x.h 00005 * PURPOSE: Base API Client Macros 00006 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 00007 */ 00008 00009 #pragma once 00010 00011 /* INCLUDES *******************************************************************/ 00012 00013 // 00014 // This macro (split it up in 3 pieces to allow for intermediary code in between) 00015 // converts a NULL-terminated ASCII string, usually associated with an object 00016 // name, into its NT-native UNICODE_STRING structure, by using the TEB's Static 00017 // Unicode String. 00018 // 00019 // It should only be used when the name is supposed to be less than MAX_PATH 00020 // (260 characters). 00021 // 00022 // It returns the correct ERROR_FILENAME_EXCED_RANGE Win32 error when the path 00023 // is too long. 00024 // 00025 // Note that Basep8BitStringToStaticUnicodeString looks deceptively similar. 00026 // However, that function was designed for File APIs, which can be switched into 00027 // a special "OEM" mode, that uses different NLS files/encoding, and thus calls 00028 // RtlOemStringToAnsiString (see SetFileApisToOEM). Thererefore, this macro and 00029 // that function are not interchangeable. As a separate note, that function uses 00030 // the *Ex version of the Rtl conversion APIs, which does stricter checking that 00031 // is not done when this macro is used. 00032 // 00033 #define ConvertAnsiToUnicodePrologue \ 00034 { \ 00035 NTSTATUS Status; \ 00036 PUNICODE_STRING UnicodeCache; \ 00037 ANSI_STRING AnsiName; 00038 #define ConvertAnsiToUnicodeBody(name) \ 00039 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString; \ 00040 RtlInitAnsiString(&AnsiName, name); \ 00041 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE); 00042 #define ConvertAnsiToUnicodeEpilogue \ 00043 if (Status == STATUS_BUFFER_OVERFLOW) \ 00044 SetLastError(ERROR_FILENAME_EXCED_RANGE); \ 00045 else \ 00046 BaseSetLastNTError(Status); \ 00047 return FALSE; \ 00048 } 00049 00050 // 00051 // This macro uses the ConvertAnsiToUnicode macros above to convert a CreateXxxA 00052 // Win32 API into its equivalent CreateXxxW API. 00053 // 00054 #define ConvertWin32AnsiObjectApiToUnicodeApi(obj, name, ...) \ 00055 ConvertAnsiToUnicodePrologue \ 00056 if (!name) return Create##obj##W(__VA_ARGS__, NULL); \ 00057 ConvertAnsiToUnicodeBody(name) \ 00058 if (NT_SUCCESS(Status)) return Create##obj##W(__VA_ARGS__, UnicodeCache->Buffer); \ 00059 ConvertAnsiToUnicodeEpilogue 00060 00061 // 00062 // This macro uses the ConvertAnsiToUnicode macros above to convert a CreateXxxA 00063 // Win32 API into its equivalent CreateXxxW API. 00064 // 00065 #define ConvertWin32AnsiObjectApiToUnicodeApi2(obj, name, ...) \ 00066 ConvertAnsiToUnicodePrologue \ 00067 if (!name) return Create##obj##W(NULL, __VA_ARGS__); \ 00068 ConvertAnsiToUnicodeBody(name) \ 00069 if (NT_SUCCESS(Status)) return Create##obj##W(UnicodeCache->Buffer, __VA_ARGS__); \ 00070 ConvertAnsiToUnicodeEpilogue 00071 00072 // 00073 // This macro uses the ConvertAnsiToUnicode macros above to convert a FindFirst*A 00074 // Win32 API into its equivalent FindFirst*W API. 00075 // 00076 #define ConvertWin32AnsiChangeApiToUnicodeApi(obj, name, ...) \ 00077 ConvertAnsiToUnicodePrologue \ 00078 ConvertAnsiToUnicodeBody(name) \ 00079 if (NT_SUCCESS(Status)) return obj##W(UnicodeCache->Buffer, ##__VA_ARGS__); \ 00080 ConvertAnsiToUnicodeEpilogue 00081 00082 // 00083 // This macro uses the ConvertAnsiToUnicode macros above to convert a OpenXxxA 00084 // Win32 API into its equivalent OpenXxxW API. 00085 // 00086 #define ConvertOpenWin32AnsiObjectApiToUnicodeApi(obj, acc, inh, name) \ 00087 ConvertAnsiToUnicodePrologue \ 00088 if (!name) \ 00089 { \ 00090 SetLastError(ERROR_INVALID_PARAMETER); \ 00091 return NULL; \ 00092 } \ 00093 ConvertAnsiToUnicodeBody(name) \ 00094 if (NT_SUCCESS(Status)) return Open##obj##W(acc, inh, UnicodeCache->Buffer);\ 00095 ConvertAnsiToUnicodeEpilogue 00096 00097 // 00098 // This macro (split it up in 3 pieces to allow for intermediary code in between) 00099 // wraps the usual code path required to create an NT object based on a Unicode 00100 // (Wide) Win32 object creation API. 00101 // 00102 // It makes use of BaseFormatObjectAttributes and allows for a custom access 00103 // mode to be used, and also sets the correct error codes in case of a collision 00104 // 00105 #define CreateNtObjectFromWin32ApiPrologue \ 00106 { \ 00107 NTSTATUS Status; \ 00108 HANDLE Handle; \ 00109 UNICODE_STRING ObjectName; \ 00110 OBJECT_ATTRIBUTES LocalAttributes; \ 00111 POBJECT_ATTRIBUTES ObjectAttributes = &LocalAttributes; 00112 #define CreateNtObjectFromWin32ApiBody(ntobj, sec, name, access, ...) \ 00113 if (name) RtlInitUnicodeString(&ObjectName, name); \ 00114 ObjectAttributes = BaseFormatObjectAttributes(&LocalAttributes, \ 00115 sec, \ 00116 name ? &ObjectName : NULL); \ 00117 Status = NtCreate##ntobj(&Handle, access, ObjectAttributes, ##__VA_ARGS__); 00118 #define CreateNtObjectFromWin32ApiEpilogue \ 00119 if (NT_SUCCESS(Status)) \ 00120 { \ 00121 if (Status == STATUS_OBJECT_NAME_EXISTS) \ 00122 SetLastError(ERROR_ALREADY_EXISTS); \ 00123 else \ 00124 SetLastError(ERROR_SUCCESS); \ 00125 return Handle; \ 00126 } \ 00127 BaseSetLastNTError(Status); \ 00128 return NULL; \ 00129 } 00130 00131 // 00132 // This macro uses the CreateNtObjectFromWin32Api macros from above to create an 00133 // NT object based on the Win32 API settings. 00134 // 00135 // Note that it is hardcoded to always use XXX_ALL_ACCESS permissions, which is 00136 // the behavior up until Vista. When/if the target moves to Vista, the macro can 00137 // be improved to support caller-specified access masks, as the underlying macro 00138 // above does support this. 00139 // 00140 #define CreateNtObjectFromWin32Api(obj, ntobj, capsobj, sec, name, ...) \ 00141 CreateNtObjectFromWin32ApiPrologue \ 00142 CreateNtObjectFromWin32ApiBody(ntobj, sec, name, capsobj##_ALL_ACCESS, ##__VA_ARGS__); \ 00143 CreateNtObjectFromWin32ApiEpilogue 00144 00145 // 00146 // This macro opens an NT object based on the Win32 API settings. 00147 // 00148 #define OpenNtObjectFromWin32Api(ntobj, acc, inh, name) \ 00149 CreateNtObjectFromWin32ApiPrologue \ 00150 if (!name) \ 00151 { \ 00152 BaseSetLastNTError(STATUS_INVALID_PARAMETER); \ 00153 return NULL; \ 00154 } \ 00155 RtlInitUnicodeString(&ObjectName, name); \ 00156 InitializeObjectAttributes(ObjectAttributes, \ 00157 &ObjectName, \ 00158 inh ? OBJ_INHERIT : 0, \ 00159 BaseGetNamedObjectDirectory(), \ 00160 NULL); \ 00161 Status = NtOpen##ntobj(&Handle, acc, ObjectAttributes); \ 00162 if (!NT_SUCCESS(Status)) \ 00163 { \ 00164 BaseSetLastNTError(Status); \ 00165 return NULL; \ 00166 } \ 00167 return Handle; \ 00168 } 00169 Generated on Fri May 25 2012 04:22:30 for ReactOS by
1.7.6.1
|