Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

752 lines
17 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. namespac.c
  5. Abstract:
  6. This file contains all of the namespace handling functions
  7. Author:
  8. Based on code by Mike Tsang (MikeTs)
  9. Stephane Plante (Splante)
  10. Environment:
  11. User mode only
  12. Revision History:
  13. --*/
  14. #include "pch.h"
  15. PNSOBJ RootNameSpaceObject;
  16. PNSOBJ CurrentScopeNameSpaceObject;
  17. PNSOBJ CurrentOwnerNameSpaceObject;
  18. NTSTATUS
  19. CreateNameSpaceObject(
  20. PUCHAR ObjectName,
  21. PNSOBJ ObjectScope,
  22. PNSOBJ ObjectOwner,
  23. PNSOBJ *Object,
  24. ULONG Flags
  25. )
  26. /*++
  27. Routine Description:
  28. This routine creates a name space object under the current scope
  29. Arguments:
  30. ObjectName - Name Path String
  31. ObjectScope - Scope to start the search from (NULL == Root)
  32. ObjectOwner - The object which owns this one
  33. Object - Where to store the point to the object that we just created
  34. Flags - Options
  35. Return Value:
  36. NTSTATUS
  37. --*/
  38. {
  39. NTSTATUS status = STATUS_SUCCESS;
  40. PNSOBJ localObject;
  41. ENTER( (
  42. 3,
  43. "CreateNameSpaceObject(%s,Scope=%s,Owner=%p,Object=%p,"
  44. "Flag=%08lx)\n",
  45. ObjectName,
  46. (ObjectScope ? LocalGetObjectPath( ObjectScope ) : "ROOT"),
  47. ObjectOwner,
  48. Object,
  49. Flags
  50. ) );
  51. if (ObjectScope == NULL) {
  52. ObjectScope = RootNameSpaceObject;
  53. }
  54. status = GetNameSpaceObject(
  55. ObjectName,
  56. ObjectScope,
  57. &localObject,
  58. NSF_LOCAL_SCOPE
  59. );
  60. if (NT_SUCCESS(status)) {
  61. if (!(Flags & NSF_EXIST_OK)) {
  62. status = STATUS_OBJECT_NAME_COLLISION;
  63. }
  64. } else if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
  65. status = STATUS_SUCCESS;
  66. //
  67. // Are we creating root?
  68. //
  69. if (strcmp(ObjectName,"\\") == 0) {
  70. ASSERT( RootNameSpaceObject == NULL );
  71. ASSERT( ObjectOwner == NULL );
  72. localObject = MEMALLOC( sizeof(NSOBJ) );
  73. if (localObject == NULL) {
  74. return STATUS_INSUFFICIENT_RESOURCES;
  75. } else {
  76. memset( localObject, 0, sizeof(NSOBJ) );
  77. localObject->dwSig = SIG_NSOBJ;
  78. localObject->dwNameSeg = NAMESEG_ROOT;
  79. RootNameSpaceObject = localObject;
  80. }
  81. } else {
  82. PUCHAR nameEnd;
  83. PNSOBJ objectParent;
  84. nameEnd = strrchr(ObjectName, '.');
  85. if (nameEnd != NULL) {
  86. *nameEnd = '\0';
  87. nameEnd++;
  88. status = GetNameSpaceObject(
  89. ObjectName,
  90. ObjectScope,
  91. &objectParent,
  92. NSF_LOCAL_SCOPE
  93. );
  94. } else if (*ObjectName == '\\') {
  95. nameEnd = &ObjectName[1];
  96. ASSERT( RootNameSpaceObject != NULL );
  97. objectParent = RootNameSpaceObject;
  98. } else if (*ObjectName == '^') {
  99. nameEnd = ObjectName;
  100. objectParent = ObjectScope;
  101. while ( (*nameEnd == '^') && (objectParent != NULL)) {
  102. objectParent = objectParent->pnsParent;
  103. nameEnd++;
  104. }
  105. } else {
  106. ASSERT( ObjectScope );
  107. nameEnd = ObjectName;
  108. objectParent = ObjectScope;
  109. }
  110. if (status == STATUS_SUCCESS) {
  111. ULONG length = strlen(nameEnd);
  112. localObject = MEMALLOC( sizeof(NSOBJ) );
  113. if (localObject == NULL) {
  114. status = STATUS_INSUFFICIENT_RESOURCES;
  115. } else if ( (*nameEnd != '\0') && (length > sizeof(NAMESEG))) {
  116. status = STATUS_OBJECT_NAME_INVALID;
  117. MEMFREE( localObject );
  118. } else {
  119. memset( localObject, 0, sizeof(NSOBJ) );
  120. localObject->dwSig = SIG_NSOBJ;
  121. localObject->dwNameSeg = NAMESEG_BLANK;
  122. memcpy( &(localObject->dwNameSeg), nameEnd, length );
  123. localObject->hOwner = ObjectOwner;
  124. localObject->pnsParent = objectParent;
  125. ListInsertTail(
  126. &(localObject->list),
  127. (PPLIST) &(objectParent->pnsFirstChild)
  128. );
  129. }
  130. }
  131. }
  132. }
  133. if (NT_SUCCESS(status) && Object != NULL) {
  134. *Object = localObject;
  135. }
  136. EXIT( (
  137. 3,
  138. "CreateNameSpaceObject=%08lx (*Object=%p)\n",
  139. status,
  140. localObject
  141. ) );
  142. return status;
  143. }
  144. NTSTATUS
  145. CreateObject(
  146. PUCHAR ObjectName,
  147. UCHAR ObjectType,
  148. PNSOBJ *Object
  149. )
  150. /*++
  151. Routine Description:
  152. Creates a NameSpace Object for the term
  153. Arguments:
  154. ObjectName - The name object object
  155. ObjectType - The type of object to create
  156. Object - Where to store a pointer to the created object
  157. Return Value:
  158. NTSTATUS
  159. --*/
  160. {
  161. NTSTATUS status = STATUS_SUCCESS;
  162. PNSOBJ localObject;
  163. ENTER( (
  164. 2,
  165. "CreateObject(%s,Type=%02x,Object=%p)\n",
  166. ObjectName,
  167. ObjectType,
  168. Object
  169. ) );
  170. status = CreateNameSpaceObject(
  171. ObjectName,
  172. CurrentScopeNameSpaceObject,
  173. CurrentOwnerNameSpaceObject,
  174. &localObject,
  175. NSF_EXIST_OK
  176. );
  177. if (NT_SUCCESS(status)) {
  178. switch (ObjectType) {
  179. case NSTYPE_UNKNOWN:
  180. break;
  181. case NSTYPE_FIELDUNIT:
  182. localObject->ObjData.dwDataType = OBJTYPE_FIELDUNIT;
  183. break;
  184. case NSTYPE_DEVICE:
  185. localObject->ObjData.dwDataType = OBJTYPE_DEVICE;
  186. break;
  187. case NSTYPE_EVENT:
  188. localObject->ObjData.dwDataType = OBJTYPE_EVENT;
  189. break;
  190. case NSTYPE_METHOD:
  191. localObject->ObjData.dwDataType = OBJTYPE_METHOD;
  192. break;
  193. case NSTYPE_MUTEX:
  194. localObject->ObjData.dwDataType = OBJTYPE_MUTEX;
  195. break;
  196. case NSTYPE_OPREGION:
  197. localObject->ObjData.dwDataType = OBJTYPE_OPREGION;
  198. break;
  199. case NSTYPE_POWERRES:
  200. localObject->ObjData.dwDataType = OBJTYPE_POWERRES;
  201. break;
  202. case NSTYPE_PROCESSOR:
  203. localObject->ObjData.dwDataType = OBJTYPE_PROCESSOR;
  204. break;
  205. case NSTYPE_THERMALZONE:
  206. localObject->ObjData.dwDataType = OBJTYPE_THERMALZONE;
  207. break;
  208. case NSTYPE_OBJALIAS:
  209. localObject->ObjData.dwDataType = OBJTYPE_OBJALIAS;
  210. break;
  211. case NSTYPE_BUFFFIELD:
  212. localObject->ObjData.dwDataType = OBJTYPE_BUFFFIELD;
  213. break;
  214. default:
  215. status = STATUS_OBJECT_TYPE_MISMATCH;
  216. }
  217. if (Object != NULL) {
  218. *Object = localObject;
  219. }
  220. }
  221. EXIT( (
  222. 2,
  223. "CreateObject=%08lx (*Object=%p)\n",
  224. status,
  225. localObject
  226. ) );
  227. return status;
  228. } //CreateObject
  229. NTSTATUS
  230. GetNameSpaceObject(
  231. PUCHAR ObjectPath,
  232. PNSOBJ ScopeObject,
  233. PNSOBJ *NameObject,
  234. ULONG Flags
  235. )
  236. /*++
  237. Routine Description:
  238. This routine searches the namespace until it finds a matching object
  239. Arguments:
  240. ObjectPath - String with the Name to search for
  241. ScopeObject - Scope to start search at (NULL == ROOT)
  242. NameObject - Where to store the object, if found
  243. Flags - Options
  244. Return Value:
  245. NTSTATUS
  246. --*/
  247. {
  248. NTSTATUS status = STATUS_SUCCESS;
  249. PUCHAR subPath;
  250. ENTER( (
  251. 3,
  252. "GetNameSpaceObject(%s,Scope=%s,Object=%p,Flags=%08lx\n",
  253. ObjectPath,
  254. (ScopeObject ? LocalGetObjectPath( ScopeObject ) : "ROOT"),
  255. NameObject,
  256. Flags
  257. ) );
  258. if (ScopeObject == NULL) {
  259. ScopeObject = RootNameSpaceObject;
  260. }
  261. if (*ObjectPath == '\\') {
  262. subPath = &ObjectPath[1];
  263. ScopeObject = RootNameSpaceObject;
  264. } else {
  265. subPath = ObjectPath;
  266. while ( (*subPath == '^') && (ScopeObject != NULL)) {
  267. subPath++;
  268. ScopeObject = ScopeObject->pnsParent;
  269. }
  270. }
  271. *NameObject = ScopeObject;
  272. if (ScopeObject == NULL) {
  273. status = STATUS_OBJECT_NAME_NOT_FOUND;
  274. } else if (*subPath != '\0') {
  275. BOOL searchUp;
  276. PNSOBJ tempObject;
  277. searchUp = (BOOL) ( !(Flags & NSF_LOCAL_SCOPE) &&
  278. (ObjectPath[0] != '\\') &&
  279. (ObjectPath[0] != '^') &&
  280. (strlen(ObjectPath) <= sizeof(NAMESEG)) );
  281. while (1) {
  282. do {
  283. tempObject = ScopeObject->pnsFirstChild;
  284. if (tempObject == NULL) {
  285. status = STATUS_OBJECT_NAME_NOT_FOUND;
  286. INFO( (5, "GetNameSpaceObject - %s has no children\n",
  287. LocalGetObjectPath( tempObject ) ) );
  288. } else {
  289. BOOL found;
  290. PUCHAR bufferEnd;
  291. ULONG length;
  292. NAMESEG dwNameSeg;
  293. bufferEnd = strchr( subPath, '.' );
  294. if (bufferEnd != NULL) {
  295. length = (ULONG)(bufferEnd - subPath);
  296. } else {
  297. length = strlen(subPath);
  298. }
  299. if (length > sizeof(NAMESEG)) {
  300. status = STATUS_OBJECT_NAME_INVALID;
  301. found = FALSE;
  302. } else {
  303. dwNameSeg = NAMESEG_BLANK;
  304. memcpy( &dwNameSeg, subPath, length );
  305. INFO( (5, "GetNameSpaceObject - Looking for %*s\n",
  306. length, subPath) );
  307. //
  308. // search all sibling fors a matching nameSeg
  309. //
  310. found = FALSE;
  311. do {
  312. INFO( (5, "GetNameSpaceObject - look at %s\n",
  313. LocalGetObjectPath( tempObject ) ) );
  314. if (tempObject->dwNameSeg == dwNameSeg) {
  315. ScopeObject = tempObject;
  316. found = TRUE;
  317. break;
  318. }
  319. tempObject = (PNSOBJ) tempObject->list.plistNext;
  320. } while (tempObject != tempObject->pnsParent->pnsFirstChild );
  321. }
  322. if (status == STATUS_SUCCESS) {
  323. if (!found) {
  324. status = STATUS_OBJECT_NAME_NOT_FOUND;
  325. } else {
  326. subPath += length;
  327. if (*subPath == '.') {
  328. subPath++;
  329. } else if (*subPath == '\0') {
  330. *NameObject = ScopeObject;
  331. break;
  332. }
  333. }
  334. }
  335. }
  336. } while ( status == STATUS_SUCCESS );
  337. if (status == STATUS_OBJECT_NAME_NOT_FOUND && searchUp &&
  338. ScopeObject != NULL && ScopeObject->pnsParent != NULL) {
  339. INFO( (5, "GetNameSpaceObject - Changing Scope to %s\n",
  340. LocalGetObjectPath( ScopeObject->pnsParent ) ) );
  341. ScopeObject = ScopeObject->pnsParent;
  342. status = STATUS_SUCCESS;
  343. } else {
  344. break;
  345. }
  346. }
  347. }
  348. if (status != STATUS_SUCCESS) {
  349. *NameObject = NULL;
  350. }
  351. EXIT( (
  352. 3,
  353. "GetNameSpaceObject=%08lx (*Object=%p)\n",
  354. status,
  355. *NameObject
  356. ) );
  357. return status;
  358. }
  359. PUCHAR
  360. GetObjectTypeName(
  361. ULONG ObjectType
  362. )
  363. /*++
  364. Routine Description:
  365. Returns a string which corresponds to the type object the object
  366. Arugment:
  367. ObjectType - The type that we wish to know about
  368. Return Value:
  369. Globally Available String
  370. --*/
  371. {
  372. PUCHAR type = NULL;
  373. ULONG i;
  374. static struct {
  375. ULONG ObjectType;
  376. PUCHAR ObjectTypeName;
  377. } ObjectTypeTable[] =
  378. {
  379. OBJTYPE_UNKNOWN, "Unknown",
  380. OBJTYPE_INTDATA, "Integer",
  381. OBJTYPE_STRDATA, "String",
  382. OBJTYPE_BUFFDATA, "Buffer",
  383. OBJTYPE_PKGDATA, "Package",
  384. OBJTYPE_FIELDUNIT, "FieldUnit",
  385. OBJTYPE_DEVICE, "Device",
  386. OBJTYPE_EVENT, "Event",
  387. OBJTYPE_METHOD, "Method",
  388. OBJTYPE_MUTEX, "Mutex",
  389. OBJTYPE_OPREGION, "OpRegion",
  390. OBJTYPE_POWERRES, "PowerResource",
  391. OBJTYPE_PROCESSOR, "Processor",
  392. OBJTYPE_THERMALZONE,"ThermalZone",
  393. OBJTYPE_BUFFFIELD, "BuffField",
  394. OBJTYPE_DDBHANDLE, "DDBHandle",
  395. OBJTYPE_DEBUG, "Debug",
  396. OBJTYPE_OBJALIAS, "ObjAlias",
  397. OBJTYPE_DATAALIAS, "DataAlias",
  398. OBJTYPE_BANKFIELD, "BankField",
  399. OBJTYPE_FIELD, "Field",
  400. OBJTYPE_INDEXFIELD, "IndexField",
  401. OBJTYPE_DATA, "Data",
  402. OBJTYPE_DATAFIELD, "DataField",
  403. OBJTYPE_DATAOBJ, "DataObject",
  404. OBJTYPE_PNP_RES, "PNPResource",
  405. OBJTYPE_RES_FIELD, "ResField",
  406. 0, NULL
  407. };
  408. ENTER( (4, "GetObjectTypeName(Type=%02x)\n", ObjectType ) );
  409. for (i = 0; ObjectTypeTable[i].ObjectTypeName != NULL; i++) {
  410. if (ObjectType == ObjectTypeTable[i].ObjectType) {
  411. type = ObjectTypeTable[i].ObjectTypeName;
  412. break;
  413. }
  414. }
  415. EXIT( (4, "GetObjectTypeName=%s\n", type ? type : "NULL" ) );
  416. return type;
  417. }
  418. PUCHAR
  419. LocalGetObjectPath(
  420. PNSOBJ NameObject
  421. )
  422. /*++
  423. Routine Description:
  424. This routine takes a NameSpace Object and returns a string to represent
  425. its path
  426. Arguments:
  427. NameObject - The object whose path we want
  428. Return Value:
  429. Pointer to the string which represents the path
  430. --*/
  431. {
  432. static UCHAR namePath[MAX_NAME_LEN + 1] = {0};
  433. ULONG i;
  434. ENTER( (6, "LocalGetObjectPath(Object=%p)\n", NameObject ) );
  435. if (NameObject != NULL) {
  436. if (NameObject->pnsParent == NULL) {
  437. strcpy(namePath, "\\");
  438. } else {
  439. LocalGetObjectPath(NameObject->pnsParent);
  440. if (NameObject->pnsParent->pnsParent != NULL) {
  441. strcat(namePath, ".");
  442. }
  443. strncat(namePath, (PUCHAR)&NameObject->dwNameSeg, sizeof(NAMESEG));
  444. }
  445. for (i = strlen(namePath) - 1; i >= 0; --i) {
  446. if (namePath[i] == '_') {
  447. namePath[i] = '\0';
  448. } else {
  449. break;
  450. }
  451. }
  452. } else {
  453. namePath[0] = '\0';
  454. }
  455. EXIT( (6, "LocalGetObjectPath=%s\n", namePath ) );
  456. return namePath;
  457. }
  458. PUCHAR
  459. RemoteGetObjectPath(
  460. ULONG_PTR ObjectAddress
  461. )
  462. /*++
  463. Routine Description:
  464. This routine takes a NameSpace Object and returns a string to represent
  465. its path
  466. Arguments:
  467. NameObject - The object whose path we want
  468. Return Value:
  469. Pointer to the string which represents the path
  470. --*/
  471. {
  472. static UCHAR namePath[MAX_NAME_LEN + 1] = {0};
  473. NSOBJ nameObject;
  474. ULONG i;
  475. ENTER( (6, "RemoteGetObjectPath(Object=%p)\n", ObjectAddress ) );
  476. if (ObjectAddress != 0 && ReadMemory( ObjectAddress, &nameObject, sizeof(nameObject), NULL) ) {
  477. if (nameObject.pnsParent == NULL) {
  478. strcpy(namePath, "\\");
  479. } else {
  480. RemoteGetObjectPath( (ULONG_PTR) nameObject.pnsParent);
  481. if (strlen(namePath) > 1) {
  482. strcat(namePath, ".");
  483. }
  484. strncat(namePath, (PUCHAR)&nameObject.dwNameSeg, sizeof(NAMESEG));
  485. }
  486. for (i = strlen(namePath) - 1; i >= 0; --i) {
  487. if (namePath[i] == '_') {
  488. namePath[i] = '\0';
  489. } else {
  490. break;
  491. }
  492. }
  493. } else {
  494. namePath[0] = '\0';
  495. }
  496. EXIT( (6, "RemoteGetObjectPath=%s\n", namePath ) );
  497. return namePath;
  498. }