| 64 | |
| 65 | |
| 66 | NTSTATUS |
| 67 | Ext2FollowLink ( |
| 68 | IN PEXT2_IRP_CONTEXT IrpContext, |
| 69 | IN PEXT2_VCB Vcb, |
| 70 | IN PEXT2_MCB Parent, |
| 71 | IN PEXT2_MCB Mcb, |
| 72 | IN ULONG Linkdep |
| 73 | ) |
| 74 | { |
| 75 | NTSTATUS Status = STATUS_LINK_FAILED; |
| 76 | |
| 77 | UNICODE_STRING UniName; |
| 78 | OEM_STRING OemName; |
| 79 | BOOLEAN bOemBuffer = FALSE; |
| 80 | |
| 81 | PEXT2_MCB Target = NULL; |
| 82 | |
| 83 | USHORT i; |
| 84 | |
| 85 | __try { |
| 86 | |
| 87 | RtlZeroMemory(&UniName, sizeof(UNICODE_STRING)); |
| 88 | RtlZeroMemory(&OemName, sizeof(OEM_STRING)); |
| 89 | |
| 90 | /* exit if we jump into a possible symlink forever loop */ |
| 91 | if ((Linkdep + 1) > EXT2_MAX_NESTED_LINKS || |
| 92 | IoGetRemainingStackSize() < 1024) { |
| 93 | __leave; |
| 94 | } |
| 95 | |
| 96 | /* read the symlink target path */ |
| 97 | if (!Mcb->Inode.i_blocks) { |
| 98 | |
| 99 | OemName.Buffer = (PUCHAR) (&Mcb->Inode.i_block[0]); |
| 100 | OemName.Length = (USHORT)Mcb->Inode.i_size; |
| 101 | OemName.MaximumLength = OemName.Length + 1; |
| 102 | |
| 103 | } else { |
| 104 | |
| 105 | OemName.Length = (USHORT)Mcb->Inode.i_size; |
| 106 | OemName.MaximumLength = OemName.Length + 1; |
| 107 | OemName.Buffer = Ext2AllocatePool(PagedPool, |
| 108 | OemName.MaximumLength, |
| 109 | 'NL2E'); |
| 110 | if (OemName.Buffer == NULL) { |
| 111 | Status = STATUS_INSUFFICIENT_RESOURCES; |
| 112 | __leave; |
| 113 | } |
| 114 | bOemBuffer = TRUE; |
| 115 | RtlZeroMemory(OemName.Buffer, OemName.MaximumLength); |
| 116 | |
| 117 | Status = Ext2ReadSymlink( |
| 118 | IrpContext, |
| 119 | Vcb, |
| 120 | Mcb, |
| 121 | OemName.Buffer, |
| 122 | (ULONG)(Mcb->Inode.i_size), |
| 123 | NULL); |
no test coverage detected