1 // ntest.cpp : Defines the entry point for the console application. 2 // 3 #include "stdafx.h" 4 #include "windows.h" 5 #include "ntndk.h" 6 7 ULONG Runs; 8 ULONG Failures; 9 10 #define TEST_ASSERT( exp ) \ 11 ((!(exp)) ? \ 12 (printf("%s, %s, %d\n", #exp, __FILE__, __LINE__), Failures++, FALSE) : \ 13 TRUE), Runs++ 14 15 HANDLE 16 SymlinkCreateTests(OUT PHANDLE OddLink) 17 { 18 NTSTATUS Status; 19 HANDLE LinkHandle; 20 UNICODE_STRING TargetName = RTL_CONSTANT_STRING(L"\\"); 21 UNICODE_STRING TargetName2 = RTL_CONSTANT_STRING(L"\\"); 22 UNICODE_STRING TargetName3 = RTL_CONSTANT_STRING(L"\\"); 23 UNICODE_STRING TargetName4 = RTL_CONSTANT_STRING(L"\\"); 24 UNICODE_STRING TargetName5 = RTL_CONSTANT_STRING(L"\\"); 25 UNICODE_STRING OkName = RTL_CONSTANT_STRING(L"\\OddLink"); 26 UNICODE_STRING OkName2 = RTL_CONSTANT_STRING(L"\\TestLink"); 27 28 // 29 // Test1: Empty Attributes 30 // 31 { 32 OBJECT_ATTRIBUTES Test1 = RTL_INIT_OBJECT_ATTRIBUTES(NULL, 0); 33 Status = NtCreateSymbolicLinkObject(&LinkHandle, 34 SYMBOLIC_LINK_ALL_ACCESS, 35 &Test1, 36 &TargetName); 37 TEST_ASSERT(NT_SUCCESS(Status)); 38 } 39 40 // 41 // Test2: No Attributes 42 // 43 { 44 POBJECT_ATTRIBUTES Test2 = NULL; 45 Status = NtCreateSymbolicLinkObject(&LinkHandle, 46 SYMBOLIC_LINK_ALL_ACCESS, 47 Test2, 48 &TargetName); 49 TEST_ASSERT(NT_SUCCESS(Status)); 50 } 51 52 // 53 // Test3: Attributes with an empty name 54 // 55 { 56 UNICODE_STRING TestName1 = {0, 0, NULL}; 57 OBJECT_ATTRIBUTES Test3 = RTL_INIT_OBJECT_ATTRIBUTES(&TestName1, 0); 58 Status = NtCreateSymbolicLinkObject(&LinkHandle, 59 SYMBOLIC_LINK_ALL_ACCESS, 60 &Test3, 61 &TargetName); 62 TEST_ASSERT(NT_SUCCESS(Status)); 63 } 64 65 // 66 // Test4: Attributes with an invalid name 67 // 68 { 69 UNICODE_STRING TestName2 = {10, 12, UlongToPtr(0x81000000)}; 70 OBJECT_ATTRIBUTES Test4 = RTL_INIT_OBJECT_ATTRIBUTES(&TestName2, 0); 71 Status = NtCreateSymbolicLinkObject(&LinkHandle, 72 SYMBOLIC_LINK_ALL_ACCESS, 73 &Test4, 74 &TargetName); 75 TEST_ASSERT(Status == STATUS_ACCESS_VIOLATION); 76 } 77 78 // 79 // Test5: Target with an odd name len 80 // 81 { 82 UNICODE_STRING OddName = RTL_CONSTANT_STRING(L"\\TestLink"); 83 OBJECT_ATTRIBUTES Test5 = RTL_INIT_OBJECT_ATTRIBUTES(&OkName, 0); 84 TargetName3.Length--; 85 Status = NtCreateSymbolicLinkObject(&LinkHandle, 86 SYMBOLIC_LINK_ALL_ACCESS, 87 &Test5, 88 &TargetName3); 89 TEST_ASSERT(Status == STATUS_INVALID_PARAMETER); 90 } 91 92 // 93 // Test6: Target with an emtpy name len 94 // 95 { 96 OBJECT_ATTRIBUTES Test5 = RTL_INIT_OBJECT_ATTRIBUTES(&OkName, 0); 97 TargetName4.MaximumLength = 0; 98 Status = NtCreateSymbolicLinkObject(&LinkHandle, 99 SYMBOLIC_LINK_ALL_ACCESS, 100 &Test5, 101 &TargetName4); 102 TEST_ASSERT(Status == STATUS_INVALID_PARAMETER); 103 } 104 105 // 106 // Test7: Target with an name len larger then maxlen 107 // 108 { 109 OBJECT_ATTRIBUTES Test6 = RTL_INIT_OBJECT_ATTRIBUTES(&OkName, 0); 110 TargetName5.Length = TargetName5.MaximumLength + 2; 111 Status = NtCreateSymbolicLinkObject(&LinkHandle, 112 SYMBOLIC_LINK_ALL_ACCESS, 113 &Test6, 114 &TargetName5); 115 TEST_ASSERT(Status == STATUS_INVALID_PARAMETER); 116 } 117 118 // 119 // Test5: Target with an odd name maxlen 120 // 121 { 122 OBJECT_ATTRIBUTES Test5 = RTL_INIT_OBJECT_ATTRIBUTES(&OkName, 0); 123 TargetName2.MaximumLength--; 124 TEST_ASSERT(TargetName2.MaximumLength % sizeof(WCHAR)); 125 Status = NtCreateSymbolicLinkObject(&LinkHandle, 126 SYMBOLIC_LINK_ALL_ACCESS, 127 &Test5, 128 &TargetName2); 129 *OddLink = LinkHandle; 130 TEST_ASSERT(NT_SUCCESS(Status)); 131 TEST_ASSERT(TargetName2.MaximumLength % sizeof(WCHAR)); 132 } 133 134 // 135 // Test6: collission 136 // 137 { 138 OBJECT_ATTRIBUTES Test6 = RTL_INIT_OBJECT_ATTRIBUTES(&OkName, 0); 139 TargetName2.MaximumLength++; 140 Status = NtCreateSymbolicLinkObject(&LinkHandle, 141 SYMBOLIC_LINK_ALL_ACCESS, 142 &Test6, 143 &TargetName2); 144 TEST_ASSERT(Status == STATUS_OBJECT_NAME_COLLISION); 145 } 146 147 // 148 // Test7: OK! 149 // 150 { 151 OBJECT_ATTRIBUTES Test7 = RTL_INIT_OBJECT_ATTRIBUTES(&OkName2, 0); 152 Status = NtCreateSymbolicLinkObject(&LinkHandle, 153 SYMBOLIC_LINK_ALL_ACCESS, 154 &Test7, 155 &TargetName2); 156 TEST_ASSERT(NT_SUCCESS(Status)); 157 } 158 159 // 160 // Return the last valid handle 161 // 162 return LinkHandle; 163 }; 164 165 166 int _tmain(int argc, _TCHAR* argv[]) 167 { 168 NTSTATUS Status; 169 HANDLE LinkHandle, OddHandle; 170 WCHAR TargetBuffer[MAX_PATH] = {0}; 171 WCHAR TargetBuffer2[MAX_PATH] = {0}; 172 UNICODE_STRING TargetName; 173 UNICODE_STRING TargetName2; 174 UNICODE_STRING OkName = RTL_CONSTANT_STRING(L"\\TestLink"); 175 ULONG NameSize; 176 177 // 178 // Start with the create tests 179 // 180 LinkHandle = SymlinkCreateTests(&OddHandle); 181 182 // 183 // Setup the two empty strings. One will have a magic-char at the end 184 // 185 RtlInitEmptyUnicodeString(&TargetName, TargetBuffer, sizeof(TargetBuffer)); 186 RtlInitEmptyUnicodeString(&TargetName2, TargetBuffer2, sizeof(TargetBuffer2)); 187 188 // 189 // Now query the odd link 190 // 191 Status = NtQuerySymbolicLinkObject(OddHandle, 192 &TargetName, 193 &NameSize); 194 TEST_ASSERT(NT_SUCCESS(Status)); 195 TEST_ASSERT(NameSize == sizeof(WCHAR)); 196 TEST_ASSERT(TargetName.Length == NameSize); 197 TEST_ASSERT(TargetName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR); 198 NtClose(OddHandle); 199 200 // 201 // Now query the test link 202 // 203 Status = NtQuerySymbolicLinkObject(LinkHandle, 204 &TargetName, 205 &NameSize); 206 TEST_ASSERT(NT_SUCCESS(Status)); 207 TEST_ASSERT(NameSize == 2 * sizeof(WCHAR)); 208 TEST_ASSERT(TargetName.Length == NameSize - sizeof(WCHAR)); 209 TEST_ASSERT(TargetName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR); 210 211 // 212 // Corrupt the characters 213 // 214 TargetName.Buffer[(NameSize - 2) / sizeof(WCHAR)] = 'v'; 215 TargetName.Buffer[(NameSize - 3) / sizeof(WCHAR)] = 'v'; 216 217 // 218 // Now query the test link 219 // 220 Status = NtQuerySymbolicLinkObject(LinkHandle, 221 &TargetName, 222 &NameSize); 223 TEST_ASSERT(NT_SUCCESS(Status)); 224 TEST_ASSERT(TargetName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR); 225 TEST_ASSERT(TargetName.Buffer[1] == UNICODE_NULL); 226 227 // 228 // Corrupt the characters 229 // 230 TargetName.Buffer[(NameSize - 2) / sizeof(WCHAR)] = 'v'; 231 TargetName.Buffer[(NameSize - 3) / sizeof(WCHAR)] = 'v'; 232 233 // 234 // Now query the test link 235 // 236 Status = NtQuerySymbolicLinkObject(LinkHandle, 237 &TargetName, 238 NULL); 239 TEST_ASSERT(NT_SUCCESS(Status)); 240 TEST_ASSERT(TargetName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR); 241 TEST_ASSERT(TargetName.Buffer[1] == 'v'); 242 243 // 244 // Print out results 245 // 246 { 247 RTL_OSVERSIONINFOW VersionInfo; 248 VersionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW); 249 RtlGetVersion(&VersionInfo); 250 printf("Test complete on: %d\n", VersionInfo.dwBuildNumber); 251 printf("Number of Failures: %d\n", Failures); 252 printf("Number of Runs: %d\n", Runs); 253 } 254 return 0; 255 } 256 257