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

Last change on this file since 5120 was 5086, checked in by bird, 25 years ago

Moved ldrCalls.h into the OS2Krnl.h tree as OS2KLDR.h.
Also moved the Ldr definitions from OS2Krnl.h and into OS2KLDR.h.

File size: 7.5 KB
Line 
1/* $Id: myldrCheckInternalName.cpp,v 1.3 2001-02-10 11:11:45 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(("ldrCheckInternalName: pMTE=0x%08x intname=%.*s path=%s rc=%d (original)\n",
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 APIRET rc; /* Return code. */
84
85
86 /*
87 * Return successfully if not library module.
88 */
89 if (!(pMTE->mte_flags1 & LIBRARYMOD))
90 return NO_ERROR;
91
92
93 /*
94 * Uppercase and parse filename in ldrpFileNameBuf
95 */
96 cchName = (int)ldrGetFileName2(ldrpFileNameBuf, (PCHAR*)SSToDS(&pachName), (PCHAR*)SSToDS(&pachExt));
97 cchExt = (pachExt) ? strlen(pachExt) : 0;
98 ldrUCaseString(pachName, cchName + cchExt + 1);
99
100
101 /*
102 * Do the compare - DllFix case or standard case.
103 */
104 if (cchName > 8
105 || ( (pMTE->mte_flags1 & CLASS_MASK) == CLASS_GLOBAL
106 && (cchExt != 3 || strcmp(pachExt, "DLL")) /* Extention != DLL. */
107 )
108 )
109 { /*
110 * Rules for long DLL names or GLOBAL dlls with extention <> DLL:
111 * 1. If DLL extention, the internal name don't need to have an extention,
112 * but it could have.
113 * 2. If not DLL extention, then internal name must have an extention.
114 * 3. If no extetion the internal name should end with a '.'.
115 */
116 PCHAR pachResName = (PCHAR)pMTE->mte_swapmte->smte_restab;
117
118 if (pachExt != NULL && cchExt == 3 && !memcmp(pachExt, "DLL", 3)) /* DLL extention. */
119 { /* (1) */
120 rc =( ( *pachResName == cchName
121 || *pachResName == cchName + cchExt + 1)
122 && !memcmp(pachResName + 1, pachName, *pachResName)
123 );
124 }
125 else if (cchExt > 0) /* Extention. */
126 { /* (2) */
127 rc =( *pachResName == cchName + cchExt + 1
128 && !memcmp(pachResName + 1, pachName, *pachResName)
129 );
130 } /* No extetion. */
131 else
132 { /* (3) */
133 rc =( *pachResName == cchName + 1
134 && pachResName[cchName + 1] == '.'
135 && !memcmp(pachResName + 1, pachName, cchName)
136 );
137 }
138 rc = (rc) ? NO_ERROR : ERROR_INVALID_NAME;
139 }
140 else
141 { /*
142 * Rules for short DLL names. ( < 8 chars):
143 * 1. The internal name must match the DLL name.
144 * 2b. If the DLL name is 8 chars the internal name could have extra chars (but we don't check).
145 * (This is a feature/bug.)
146 * 2a. If the DLL name is less than 8 chars the internal name should match exactly.
147 */
148 #if 0
149 /* This was the way it should be implemented, but code is buggy.
150 * Current code works like this:
151 * rc =( memcmp(pachName, pMTE->mte_modname, cchName)
152 * && ( cchName == 8
153 * || pMTE->mte_modname[cchName] == '\0'
154 * )
155 * ) ? ERROR_INVALID_NAME : NO_ERROR;
156 *
157 * This is so old that it has become an persistant bug in some ways.
158 * The correct check will break Lotus Freelance for example.
159 * But, the applications which are broken all seems to include the
160 * .DLL extention in the internal name (and have length which is
161 * shorter than 8 chars).
162 * So, a correction will simply be to remove any .DLL extention
163 * of the internal name before setting it ldrCreateMte. This fix
164 * could always be done here too.
165 *
166 * BTW. I managed to exploit this bug to replace doscall1.dll.
167 * Which is very nasty!
168 */
169 rc =( !memcmp(pachName, pMTE->mte_modname, cchName) /* (1) */
170 && ( cchName == 8 /* (2a) */
171 || pMTE->mte_modname[cchName] == '\0' /* (2b) */
172 )
173 ) ? NO_ERROR : ERROR_INVALID_NAME;
174 #else
175 /* For the issue of compatibly with the bug we'll call the real function. */
176 rc = ldrCheckInternalName(pMTE);
177 #endif
178 }
179
180
181 /*
182 * Log answer and return it.
183 */
184 kprintf(("myldrCheckInternalName: pMTE=0x%08x intname=%.*s path=%s rc=%d\n",
185 pMTE, *(PCHAR)pMTE->mte_swapmte->smte_restab, (PCHAR)pMTE->mte_swapmte->smte_restab + 1, ldrpFileNameBuf, rc));
186
187 return rc;
188}
189
Note: See TracBrowser for help on using the repository browser.