source: trunk/src/win32k/ldr/myldrCheckInternalName.cpp

Last change on this file was 6193, checked in by bird, 24 years ago

Logging and strcmp -> memcmp.

File size: 7.6 KB
Line 
1/* $Id: myldrCheckInternalName.cpp,v 1.5 2001-07-07 04:39:57 bird Exp $
2 *
3 * ldrCheckInternalName - ldrCheckInternalName replacement with support for
4 * long DLL names and no .DLL-extention dependency.
5 *
6 * Copyright (c) 1999-2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11
12
13/*******************************************************************************
14* Defined Constants And Macros *
15*******************************************************************************/
16#define INCL_DOSERRORS
17#define INCL_NOPMAPI
18#define INCL_OS2KRNL_LDR
19
20
21/*******************************************************************************
22* Header Files *
23*******************************************************************************/
24#include <os2.h>
25
26#include <memory.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include "devSegDf.h" /* Win32k segment definitions. */
31#include "log.h"
32#include "avl.h"
33#include <peexe.h>
34#include <exe386.h>
35#include "OS2Krnl.h"
36#include "dev32.h"
37#include "ldr.h"
38#include "options.h"
39
40
41/**
42 * Checks if the internal name (first name in the resident nametable) matches
43 * the filename.
44 *
45 * This replacement will support DLLs with non DLL extention
46 * and names that are longer than 8 chars.
47 *
48 * @returns NO_ERROR on success (the name matched).
49 * ERROR_INVALID_NAME if mismatch.
50 * @param pMTE Pointer to the MTE of the module to check.<br>
51 * Assumes! that the filename for this module is present in ldrpFileNameBuf.
52 * @sketch Check if library module - this check only applies to library modules (ie. DLLs).
53 * Uppercase filename.
54 * Parse filename - get the length of the name including any extention different from .DLL.
55 * Compare internal name and filename returning NO_ERROR if matches and errorcode if mismatch.
56 * If this module is not in the GLOBAL CLASS we don't compare the extention.
57 *
58 * @remark This function will have to change slightly when we're starting to
59 * support ELF shared libraries (ie. .so-files).
60 */
61ULONG LDRCALL myldrCheckInternalName(PMTE pMTE)
62{
63 /* Check if this feature is enabled */
64 if (isDllFixesDisabled())
65 {
66 #ifdef DEBUG
67 APIRET rc = ldrCheckInternalName(pMTE);
68 kprintf(("myldrCheckInternalName: pMTE=0x%08x intname=%.*s path=%s rc=%d\n", /* (original)\",*/
69 pMTE, *(PCHAR)pMTE->mte_swapmte->smte_restab, (PCHAR)pMTE->mte_swapmte->smte_restab + 1, ldrpFileNameBuf, rc));
70 return rc;
71 #else
72 return ldrCheckInternalName(pMTE);
73 #endif
74 }
75
76 /* Local Variables */
77 PCHAR pachName; /* Pointer to the name part of pachFilename. */
78 int cchName; /* Length of the name part of pachFilename.
79 * Includes extention if extention is not .DLL.
80 * this is the length relative to pachName used to match the internal name. */
81 PCHAR pachExt; /* Pointer to the extention part of pachFilename. (not dot!) */
82 int cchExt; /* Length of the extention part of pachFilename. (not dot!) */
83 PCHAR pachResName; /* Pointer to the internal name - resname.0 */
84 APIRET rc; /* Return code. */
85
86
87 /*
88 * Return successfully if not library module.
89 */
90 if (!(pMTE->mte_flags1 & LIBRARYMOD))
91 return NO_ERROR;
92
93
94 /*
95 * Uppercase and parse filename in ldrpFileNameBuf
96 */
97 cchName = (int)ldrGetFileName2(ldrpFileNameBuf, (PCHAR*)SSToDS(&pachName), (PCHAR*)SSToDS(&pachExt));
98 cchExt = (pachExt) ? strlen(pachExt) : 0;
99 ldrUCaseString(pachName, cchName + cchExt + 1);
100 pachResName = (PCHAR)pMTE->mte_swapmte->smte_restab;
101
102 /*
103 * Do the compare - DllFix case or standard case.
104 */
105 if ( (cchName > 8 && *pachResName > 8)
106 || ( (pMTE->mte_flags1 & CLASS_MASK) == CLASS_GLOBAL
107 && (cchExt != 3 || memcmp(pachExt, "DLL", 3)) /* Extention != DLL. */
108 )
109 )
110 { /*
111 * Rules for long DLL names or GLOBAL dlls with extention <> DLL:
112 * 1. If DLL extention, the internal name don't need to have an extention,
113 * but it could have.
114 * 2. If not DLL extention, then internal name must have an extention.
115 * 3. If no extention the internal name should end with a '.'.
116 */
117 if (pachExt != NULL && cchExt == 3 && !memcmp(pachExt, "DLL", 3)) /* DLL extention. */
118 { /* (1) */
119 rc =( ( *pachResName == cchName
120 || *pachResName == cchName + cchExt + 1)
121 && !memcmp(pachResName + 1, pachName, *pachResName)
122 );
123 }
124 else if (cchExt > 0) /* Extention. */
125 { /* (2) */
126 rc =( *pachResName == cchName + cchExt + 1
127 && !memcmp(pachResName + 1, pachName, *pachResName)
128 );
129 } /* No extetion. */
130 else
131 { /* (3) */
132 rc =( *pachResName == cchName + 1
133 && pachResName[cchName + 1] == '.'
134 && !memcmp(pachResName + 1, pachName, cchName)
135 );
136 }
137 rc = (rc) ? NO_ERROR : ERROR_INVALID_NAME;
138 }
139 else
140 { /*
141 * Rules for short DLL names. ( < 8 chars):
142 * 1. The internal name must match the DLL name.
143 * 2b. If the DLL name is 8 chars the internal name could have extra chars (but we don't check).
144 * (This is a feature/bug.)
145 * 2a. If the DLL name is less than 8 chars the internal name should match exactly.
146 */
147 #if 0
148 /* This was the way it should be implemented, but code is buggy.
149 * Current code works like this:
150 * rc =( memcmp(pachName, pMTE->mte_modname, cchName)
151 * && ( cchName == 8
152 * || pMTE->mte_modname[cchName] == '\0'
153 * )
154 * ) ? ERROR_INVALID_NAME : NO_ERROR;
155 *
156 * This is so old that it has become an persistant bug in some ways.
157 * The correct check will break Lotus Freelance for example.
158 * But, the applications which are broken all seems to include the
159 * .DLL extention in the internal name (and have length which is
160 * shorter than 8 chars).
161 * So, a correction will simply be to remove any .DLL extention
162 * of the internal name before setting it ldrCreateMte. This fix
163 * could always be done here too.
164 *
165 * BTW. I managed to exploit this bug to replace doscall1.dll.
166 * Which is very nasty!
167 */
168 rc =( !memcmp(pachName, pMTE->mte_modname, cchName) /* (1) */
169 && ( cchName == 8 /* (2a) */
170 || pMTE->mte_modname[cchName] == '\0' /* (2b) */
171 )
172 ) ? NO_ERROR : ERROR_INVALID_NAME;
173 #else
174 /* For the issue of compatibly with the bug we'll call the real function. */
175 rc = ldrCheckInternalName(pMTE);
176 #endif
177 }
178
179
180 /*
181 * Log answer and return it.
182 */
183 kprintf(("myldrCheckInternalName: pMTE=0x%08x intname=%.*s path=%s rc=%d\n",
184 pMTE, *(PCHAR)pMTE->mte_swapmte->smte_restab, (PCHAR)pMTE->mte_swapmte->smte_restab + 1, ldrpFileNameBuf, rc));
185
186 return rc;
187}
188
Note: See TracBrowser for help on using the repository browser.