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

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

Fixed two bugs in the ldrCheckInternalName replacement which are
relally features/bugs in OS/2.

File size: 7.5 KB
Line 
1/* $Id: myldrCheckInternalName.cpp,v 1.2 2001-01-08 18:04:23 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
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#include <os2.h>
24
25#include <memory.h>
26#include <stdlib.h>
27#include <string.h>
28
29#include "devSegDf.h" /* Win32k segment definitions. */
30#include "log.h"
31#include "avl.h"
32#include <peexe.h>
33#include <exe386.h>
34#include "OS2Krnl.h"
35#include "dev32.h"
36#include "ldr.h"
37#include "ldrCalls.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.