Source code of Windows XP (NT5)
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.

685 lines
16 KiB

  1. //============================================================================
  2. // Copyright (c) 1995, Microsoft Corporation
  3. //
  4. // File: Upgrade.c
  5. //
  6. // History:
  7. // V Raman July-1-1997 Created.
  8. //
  9. // Entry points for ISDN upgrade
  10. //============================================================================
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <setupapi.h>
  16. #include <tchar.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include "upgrade.h"
  20. //
  21. // upgrade inf section name
  22. //
  23. #define MAX_CHARS_PER_LINE 128
  24. #define ALIGN_SIZE 0x00000008
  25. #define ALIGN_SHIFT (ALIGN_SIZE - 0x00000001) // 0x00000007
  26. #define ALIGN_MASK (~ALIGN_SHIFT) // 0xfffffff8
  27. #define ALIGN_POINTER(ptr) { \
  28. ((DWORD) (ptr)) += ALIGN_SHIFT; \
  29. ((DWORD) (ptr)) &= ALIGN_MASK; \
  30. }
  31. typedef struct _ISDN_STATIC_PARAMS
  32. {
  33. WCHAR ptszInfId[ MAX_PATH ];
  34. DWORD dwWanEndPoints;
  35. DWORD dwNumDChannels;
  36. DWORD dwNumBChannelsPerDChannel;
  37. } ISDN_STATIC_PARAMS, *PISDN_STATIC_PARAMS;
  38. //
  39. // New inf Key names
  40. //
  41. WCHAR c_ptszIsdnNumDChannels[] = L"IsdnNumDChannels";
  42. WCHAR c_ptszIsdnSwitchType[] = L"IsdnSwitchType";
  43. WCHAR c_ptszIsdnNumBChannels[] = L"IsdnNumBChannels";
  44. WCHAR c_ptszIsdnSpid[] = L"IsdnSpid";
  45. WCHAR c_ptszIsdnPhoneNumber[] = L"IsdnPhoneNumber";
  46. //============================================================================
  47. // Values for DIGI Datafire ISDN cards.
  48. //
  49. //
  50. //============================================================================
  51. #define DIGI_MAX_ADAPTERS 3
  52. #define DIGI_MAX_SWITCH_TYPES 12
  53. ISDN_STATIC_PARAMS g_ispDigiParams[] =
  54. {
  55. { TEXT( "DataFireIsa1U" ), 2, 1, 2 },
  56. { L "DataFireIsa1ST" , 2, 1, 2 },
  57. { L "DataFireIsa4ST" , 8, 4, 2 }
  58. };
  59. PWSTR g_ptszDigiSwitchTypes[] =
  60. {
  61. L "Auto Detect" ,
  62. L "Generic" ,
  63. L "ATT" ,
  64. L "DEFINITY" ,
  65. L "NTI" ,
  66. L "NI1" ,
  67. L "NET3" ,
  68. L "1TR6" ,
  69. L "VN3" ,
  70. L "INS64" ,
  71. L "AUSTEL" ,
  72. L "Singapore"
  73. };
  74. //
  75. // registry keys for DIGI Datafire ISDN card.
  76. //
  77. WCHAR c_ptszNumberOfLines[] = L "NumberOfLines" ;
  78. WCHAR c_ptszLine[] = L "Line" ;
  79. WCHAR c_ptszSwitchStyle[] = L "SwitchStyle" ;
  80. WCHAR c_ptszLogicalTerminals[] = L "LogicalTerminals" ;
  81. WCHAR c_ptszTerminalManagement[] = L "TerminalManagement" ;
  82. WCHAR c_ptszLTerm[] = L "LTerm" ;
  83. WCHAR c_ptszSPID[] = L "SPID" ;
  84. WCHAR c_ptszAddress[] = L "Address" ;
  85. //----------------------------------------------------------------------------
  86. // Function: DLLMAIN
  87. //
  88. // This is the DLL entrypoint handler.
  89. //----------------------------------------------------------------------------
  90. BOOL
  91. WINAPI
  92. DLLMAIN(
  93. HINSTANCE hInstance,
  94. DWORD dwReason,
  95. PVOID pUnused
  96. )
  97. {
  98. switch(dwReason) {
  99. case DLL_PROCESS_ATTACH:
  100. DisableThreadLibraryCalls(hInstance);
  101. break;
  102. case DLL_PROCESS_DETACH:
  103. break;
  104. default:
  105. break;
  106. }
  107. return TRUE;
  108. }
  109. //----------------------------------------------------------------------------
  110. // Function: NetWriteDIGIISDNRegistry
  111. //
  112. // reads the registry layout of DIGI PCIMAC card and write the key
  113. // values that need to be updated in the 5.0 setup.
  114. //----------------------------------------------------------------------------
  115. DWORD
  116. NetWriteDIGIISDNRegistry(
  117. IN HKEY hKeyInstanceParameters,
  118. IN PCWSTR szPreNT5IndId,
  119. IN PCWSTR szNT5InfId,
  120. IN PCWSTR szSectionName,
  121. OUT PWSTR ** lplplpBuffer,
  122. IN OUT PDWORD pdwNumLines
  123. )
  124. {
  125. DWORD dwInd = 0, dwInd1 = 0, dwErr = ERROR_SUCCESS;
  126. DWORD dwMaxKeyLen = 0, dwMaxValueLen = 0, dwType = 0, dwSize = 0,
  127. dwNumSubKeys = 0;
  128. DWORD dwValue = 0, dwNumDChannels = 0, dwNumLogTerm = 0;
  129. DWORD dwMaxLines = 0, dwNumLines = 0;
  130. PTCHAR ptszKey = NULL, ptszValue = NULL;
  131. PTCHAR ptszBuffer = NULL;
  132. WCHAR ptszSubKey[ MAX_PATH ];
  133. PBYTE pb = NULL, pbLine = NULL;
  134. PWSTR * lplpOffset;
  135. PISDN_STATIC_PARAMS pisp = NULL;
  136. do
  137. {
  138. //
  139. // Create IsdnNumDChannel entry
  140. //
  141. // for each D channel
  142. // Create IsdnSwitchType (index into the mulptsz)
  143. // Create VendorSpecific\TerminalManagement
  144. // Create VendorSpecific\LogicalTerminals
  145. //
  146. // For each B Channel
  147. // Create IsdnSpid
  148. // Create IsdnPhoneNumber
  149. //
  150. //
  151. // figure out which card this is
  152. //
  153. for ( dwInd = 0; dwInd < DIGI_MAX_ADAPTERS; dwInd++ )
  154. {
  155. if ( !_wcsicmp( g_ispDigiParams[ dwInd ].ptszInfId, szNT5InfId ) )
  156. {
  157. break;
  158. }
  159. }
  160. if ( dwInd >= DIGI_MAX_ADAPTERS )
  161. {
  162. break;
  163. }
  164. pisp = &(g_ispDigiParams[ dwInd ]);
  165. // Compute number of lines in buffer as
  166. //
  167. // 4 (section name, Addreg line, blank line, Addreg section name) +
  168. // 1 (IsdnNumDChannels) +
  169. // IsdnNumDChannels * ( 3 +
  170. // ( IsdnNumBChannels * 2 )
  171. //
  172. dwMaxLines = 5 +
  173. ( pisp-> dwNumDChannels *
  174. ( 3 + pisp-> dwNumBChannelsPerDChannel * 2 ) );
  175. //
  176. // allocate buffer big enough to hold these many lines of entries
  177. //
  178. dwSize = sizeof( PWSTR ) * dwMaxLines + ALIGN_SIZE +
  179. dwMaxLines * sizeof( WCHAR ) * MAX_CHARS_PER_LINE;
  180. pb = LocalAlloc( 0, dwSize );
  181. if ( pb == NULL )
  182. {
  183. break;
  184. }
  185. ZeroMemory( pb, dwSize );
  186. lplpOffset = (PWSTR *) pb;
  187. pbLine = pb + sizeof( PWSTR ) * dwMaxLines;
  188. ALIGN_POINTER( pbLine );
  189. //
  190. // set the pointers
  191. //
  192. for ( dwInd = 0; dwInd < dwMaxLines; dwInd++ )
  193. {
  194. lplpOffset[ dwInd ] = (PWSTR) ( pbLine +
  195. dwInd * sizeof( WCHAR ) * MAX_CHARS_PER_LINE );
  196. }
  197. //
  198. // write section name
  199. //
  200. dwNumLines = 0;
  201. ptszBuffer = lplpOffset[ dwNumLines++ ];
  202. wsprintfW( ptszBuffer, L"[%s]", szSectionName );
  203. ptszBuffer = lplpOffset[ dwNumLines++ ];
  204. wsprintfW(
  205. ptszBuffer,
  206. L"AddReg\t= %s.%s.reg",
  207. szSectionName,
  208. szNT5InfId
  209. );
  210. //
  211. // Start registry section name
  212. //
  213. ptszBuffer = lplpOffset[ dwNumLines++ ];
  214. wsprintfW(
  215. ptszBuffer,
  216. L"[%s.%s.reg]",
  217. szSectionName,
  218. szNT5InfId
  219. );
  220. //
  221. // Find size of longest sub key and the size of max value
  222. // Allocate buffers for them.
  223. //
  224. dwErr = RegQueryInfoKey(
  225. hKeyInstanceParameters,
  226. NULL,
  227. NULL,
  228. NULL,
  229. NULL,
  230. NULL,
  231. NULL,
  232. NULL,
  233. &dwMaxKeyLen,
  234. &dwMaxValueLen,
  235. NULL,
  236. NULL
  237. );
  238. if ( dwErr != ERROR_SUCCESS )
  239. {
  240. dwErr = GetLastError();
  241. break;
  242. }
  243. ptszKey = HeapAlloc(
  244. GetProcessHeap(),
  245. 0,
  246. (dwMaxKeyLen + 1) * sizeof( WCHAR )
  247. );
  248. if ( ptszKey == NULL )
  249. {
  250. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  251. break;
  252. }
  253. ptszValue = HeapAlloc(
  254. GetProcessHeap(),
  255. 0,
  256. (dwMaxValueLen + 1) * sizeof( WCHAR )
  257. );
  258. if ( ptszValue == NULL )
  259. {
  260. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  261. break;
  262. }
  263. //
  264. // Find number of D channels
  265. //
  266. dwSize = sizeof( DWORD );
  267. dwErr = RegQueryValueEx(
  268. hKeyInstanceParameters,
  269. c_ptszNumberOfLines,
  270. NULL,
  271. &dwType,
  272. (PBYTE) &dwNumDChannels,
  273. &dwSize
  274. );
  275. if ( dwErr != ERROR_SUCCESS )
  276. {
  277. break;
  278. }
  279. ptszBuffer = lplpOffset[ dwNumLines++ ];
  280. wsprintfW(
  281. ptszBuffer,
  282. L "HKR, , %s, %#.8lx, %d" ,
  283. c_ptszIsdnNumDChannels,
  284. FLG_ADDREG_TYPE_DWORD,
  285. dwNumDChannels
  286. );
  287. ptszBuffer = lplpOffset[ dwNumLines++ ];
  288. //
  289. // for each D channel
  290. //
  291. for ( dwInd = 0; dwInd < dwNumDChannels; dwInd++ )
  292. {
  293. //
  294. // Sub key for D channels under which all the info
  295. // is to written
  296. //
  297. wsprintfW( ptszSubKey, L"%d" , dwInd );
  298. //
  299. // create switch type key name
  300. //
  301. wsprintfW( ptszKey, L"%s%d.%s" , c_ptszLine, dwInd, c_ptszSwitchStyle );
  302. //
  303. // query protocol key and use look up to determine switch type.
  304. //
  305. dwSize = dwMaxValueLen * sizeof( WCHAR );
  306. dwErr = RegQueryValueEx(
  307. hKeyInstanceParameters,
  308. ptszKey,
  309. NULL,
  310. &dwType,
  311. (LPBYTE) ptszValue,
  312. &dwSize
  313. );
  314. if ( dwErr != ERROR_SUCCESS )
  315. {
  316. break;
  317. }
  318. //
  319. // lookup the switchtype in the list of switch types
  320. //
  321. for ( dwInd1 = 0; dwInd1 < DIGI_MAX_SWITCH_TYPES; dwInd1++ )
  322. {
  323. if ( !_wcsicmp( g_ptszDigiSwitchTypes[ dwInd1 ], ptszValue ) )
  324. {
  325. break;
  326. }
  327. }
  328. if ( dwInd1 >= DIGI_MAX_SWITCH_TYPES )
  329. {
  330. dwInd1 = 1;
  331. }
  332. wsprintfW(
  333. ptszBuffer,
  334. L "HKR, %s, %s, %#.8lx, %d" ,
  335. ptszSubKey,
  336. c_ptszIsdnSwitchType,
  337. FLG_ADDREG_TYPE_DWORD,
  338. dwInd1
  339. );
  340. ptszBuffer = lplpOffset[ dwNumLines++ ];
  341. //
  342. // Create key for number of B channels
  343. //
  344. wsprintfW(
  345. ptszKey,
  346. L"%s%d.%s" ,
  347. c_ptszLine, dwInd, c_ptszLogicalTerminals
  348. );
  349. //
  350. // Find and write number of logical terminals
  351. //
  352. dwSize = sizeof( DWORD );
  353. dwErr = RegQueryValueEx(
  354. hKeyInstanceParameters,
  355. ptszKey,
  356. NULL,
  357. &dwType,
  358. (LPBYTE) &dwNumLogTerm,
  359. &dwSize
  360. );
  361. if ( dwErr != ERROR_SUCCESS )
  362. {
  363. break;
  364. }
  365. wsprintfW(
  366. ptszBuffer,
  367. L "HKR, %s\\VendorSpecific, %s, %#.8lx, %d" ,
  368. ptszSubKey,
  369. c_ptszLogicalTerminals,
  370. FLG_ADDREG_TYPE_DWORD,
  371. dwNumLogTerm
  372. );
  373. ptszBuffer = lplpOffset[ dwNumLines++ ];
  374. //
  375. // Create key for Terminal management
  376. //
  377. wsprintfW(
  378. ptszKey,
  379. L"%s%d.%s" ,
  380. c_ptszLine, dwInd, c_ptszTerminalManagement
  381. );
  382. //
  383. // Find and write terminal management value
  384. //
  385. dwSize = dwMaxValueLen * sizeof( WCHAR );
  386. dwErr = RegQueryValueEx(
  387. hKeyInstanceParameters,
  388. ptszKey,
  389. NULL,
  390. &dwType,
  391. (LPBYTE) ptszValue,
  392. &dwSize
  393. );
  394. if ( dwErr != ERROR_SUCCESS )
  395. {
  396. break;
  397. }
  398. wsprintfW(
  399. ptszBuffer,
  400. L "HKR, %s\\VendorSpecific, %s, %#.8lx, %s" ,
  401. ptszSubKey,
  402. c_ptszTerminalManagement,
  403. FLG_ADDREG_TYPE_SZ,
  404. ptszValue
  405. );
  406. ptszBuffer = lplpOffset[ dwNumLines++ ];
  407. //
  408. // for each B Channel for this D channels write the
  409. // B channel info.
  410. //
  411. for ( dwInd1 = 0; dwInd1 < pisp-> dwNumBChannelsPerDChannel; dwInd1++ )
  412. {
  413. //
  414. // sub key for B channel under which all the info. is to
  415. // be written.
  416. //
  417. wsprintfW( ptszSubKey, L"%d\\%d" , dwInd, dwInd1 );
  418. //
  419. // create key for SPID
  420. //
  421. wsprintfW(
  422. ptszKey, L"%s%d.%s%d.%s" ,
  423. c_ptszLine, dwInd, c_ptszLTerm, dwInd1, c_ptszSPID
  424. );
  425. //
  426. // retrieve and write value of SPID key
  427. //
  428. dwSize = dwMaxValueLen * sizeof( WCHAR );
  429. dwErr = RegQueryValueEx(
  430. hKeyInstanceParameters,
  431. ptszKey,
  432. NULL,
  433. &dwType,
  434. (LPBYTE) ptszValue,
  435. &dwSize
  436. );
  437. if ( dwErr != ERROR_SUCCESS )
  438. {
  439. dwErr = ERROR_SUCCESS;
  440. break;
  441. }
  442. wsprintfW(
  443. ptszBuffer,
  444. L "HKR, %s, %s, %#.8lx, %s" ,
  445. ptszSubKey,
  446. c_ptszIsdnSpid,
  447. FLG_ADDREG_TYPE_SZ,
  448. ptszValue
  449. );
  450. ptszBuffer = lplpOffset[ dwNumLines++ ];
  451. //
  452. // create key for Phone Number
  453. //
  454. wsprintfW(
  455. ptszKey, L"%s%d.%s%d.%s" ,
  456. c_ptszLine, dwInd, c_ptszLTerm, dwInd1, c_ptszAddress
  457. );
  458. //
  459. // retrieve and write value of phone number key
  460. //
  461. dwSize = dwMaxValueLen * sizeof( WCHAR );
  462. dwErr = RegQueryValueEx(
  463. hKeyInstanceParameters,
  464. ptszKey,
  465. NULL,
  466. &dwType,
  467. (LPBYTE) ptszValue,
  468. &dwSize
  469. );
  470. if ( dwErr != ERROR_SUCCESS )
  471. {
  472. dwErr = ERROR_SUCCESS;
  473. break;
  474. }
  475. wsprintfW(
  476. ptszBuffer,
  477. L"HKR, %s, %s, %#.8lx, %s" ,
  478. ptszSubKey,
  479. c_ptszIsdnPhoneNumber,
  480. FLG_ADDREG_TYPE_SZ,
  481. ptszValue
  482. );
  483. ptszBuffer = lplpOffset[ dwNumLines++ ];
  484. }
  485. if ( dwErr != ERROR_SUCCESS )
  486. {
  487. break;
  488. }
  489. }
  490. } while ( FALSE );
  491. //
  492. // clean up
  493. //
  494. if ( ptszKey ) { HeapFree( GetProcessHeap(), 0, ptszKey ); }
  495. if ( ptszValue ) { HeapFree( GetProcessHeap(), 0, ptszValue ); }
  496. if ( dwErr == ERROR_SUCCESS )
  497. {
  498. *lplplpBuffer =(PWSTR *) pb;
  499. *pdwNumLines = dwNumLines;
  500. }
  501. return dwErr;
  502. }