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.

419 lines
12 KiB

  1. // DVDUpgrd.cpp : Defines the entry point for the application.
  2. //
  3. #define ASSERTERROR(x) ASSERT( ! x )
  4. #include <windows.h>
  5. #include <streams.h>
  6. #include "..\dvddetect\DVDDetect.h"
  7. // for IShellLink
  8. #include <wininet.h> // must include before shlobj to get IActiveDesktop
  9. #include <shlobj.h>
  10. #include <Userenv.h>
  11. #include <intshcut.h>
  12. #include <shellapi.h>
  13. #define DBGBOX(x)
  14. static TCHAR* Append( TCHAR* pOut, const TCHAR* pString )
  15. {
  16. lstrcat( pOut, pString );
  17. return pOut + lstrlen(pOut);
  18. }
  19. static TCHAR* Print(TCHAR* pOut, const DVDResult& result)
  20. {
  21. UINT64 ullVersion = result.GetVersion();
  22. wsprintf( pOut,
  23. TEXT("Name:\"%s\"\n Company Name:\"%s\"\n Version: %d.%d.%d.%d \n CRC32: 0x%08x\n"),
  24. result.GetName(),
  25. result.GetCompanyName(),
  26. WORD(ullVersion>>48),
  27. WORD(ullVersion>>32),
  28. WORD(ullVersion>>16),
  29. WORD(ullVersion>>0),
  30. result.GetCRC()
  31. );
  32. return pOut + lstrlen(pOut );
  33. }
  34. //
  35. // Generic utility functions
  36. //
  37. static bool AreEquivalent( const char* pStr1, const char* pStr2 )
  38. {
  39. return lstrcmpiA( pStr1, pStr2 ) ==0;
  40. }
  41. static bool AreEquivalent( const WCHAR* pStr1, const WCHAR* pStr2 )
  42. {
  43. return lstrcmpiW( pStr1, pStr2 ) ==0;
  44. }
  45. static bool IsUserMemberOf( DWORD domainAlias )
  46. {
  47. HANDLE Token;
  48. DWORD BytesRequired;
  49. PTOKEN_GROUPS Groups;
  50. bool b;
  51. DWORD i;
  52. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  53. PSID AdministratorsGroup;
  54. //
  55. // Open the process token.
  56. //
  57. if(!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&Token)) {
  58. return(false);
  59. }
  60. b = false;
  61. Groups = NULL;
  62. //
  63. // Get group information.
  64. //
  65. if(!GetTokenInformation(Token,TokenGroups,NULL,0,&BytesRequired)
  66. && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  67. && (Groups = reinterpret_cast<PTOKEN_GROUPS>(new BYTE[BytesRequired]) )
  68. && GetTokenInformation(Token,TokenGroups,Groups,BytesRequired,&BytesRequired)) {
  69. if( AllocateAndInitializeSid(
  70. &NtAuthority,
  71. 2,
  72. SECURITY_BUILTIN_DOMAIN_RID,
  73. domainAlias,
  74. 0, 0, 0, 0, 0, 0,
  75. &AdministratorsGroup
  76. ))
  77. {
  78. //
  79. // See if the user has the administrator group.
  80. //
  81. for(i=0; i<Groups->GroupCount; i++) {
  82. if(EqualSid(Groups->Groups[i].Sid,AdministratorsGroup)) {
  83. b = true;
  84. break;
  85. }
  86. }
  87. FreeSid(AdministratorsGroup);
  88. }
  89. }
  90. //
  91. // Clean up and return.
  92. //
  93. if(Groups) {
  94. delete [] (BYTE *)Groups;
  95. }
  96. CloseHandle(Token);
  97. return(b);
  98. }
  99. // copied from ntfs\fu\utility
  100. static bool IsUserAdmin()
  101. {
  102. return IsUserMemberOf( DOMAIN_ALIAS_RID_ADMINS);
  103. }
  104. static bool IsUserPowerUser()
  105. {
  106. return IsUserMemberOf( DOMAIN_ALIAS_RID_POWER_USERS );
  107. }
  108. static HRESULT CreateShortcutToURL(LPCTSTR pszURL, LPCTSTR pszLinkFile)
  109. {
  110. CoInitialize(NULL);
  111. HRESULT hRes;
  112. IUniformResourceLocator *pURL = NULL;
  113. // Create an IUniformResourceLocator object
  114. hRes = CoCreateInstance (CLSID_InternetShortcut, NULL,
  115. CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (LPVOID*) &pURL);
  116. if (SUCCEEDED(hRes)) {
  117. IPersistFile *pPF = NULL;
  118. hRes = pURL->SetURL(pszURL, IURL_SETURL_FL_USE_DEFAULT_PROTOCOL );
  119. if (SUCCEEDED(hRes)) {
  120. hRes = pURL->QueryInterface (IID_IPersistFile, (void **)&pPF);
  121. if (SUCCEEDED(hRes)) {
  122. #ifndef UNICODE
  123. WCHAR wsz [MAX_PATH]; // buffer for Unicode string
  124. // Ensure that the string consists of ANSI characters.
  125. MultiByteToWideChar (CP_ACP, 0, pszLinkFile, -1, wsz, MAX_PATH);
  126. // Save the shortcut via the IPersistFile::Save member function.
  127. hRes = pPF->Save (wsz, TRUE);
  128. #else
  129. hRes = pPF->Save (pszLinkFile, TRUE);
  130. #endif
  131. // Release the pointer to IPersistFile.
  132. pPF->Release ();
  133. }
  134. }
  135. // Release the pointer to IUniformResourceLocator
  136. pURL->Release ();
  137. }
  138. CoUninitialize();
  139. return hRes;
  140. }
  141. static bool IsAlphaNum( TCHAR t )
  142. {
  143. return ( TEXT('a') <= t && t<= TEXT('z')) ||
  144. ( TEXT('A') <= t && t<= TEXT('Z')) ||
  145. ( TEXT('0') <= t && t<= TEXT('9'));
  146. }
  147. void AlphaNumStrCpy( TCHAR* pOut, const TCHAR* pIn )
  148. {
  149. while( *pIn ) {
  150. if( IsAlphaNum(*pIn)) {
  151. *pOut++ = *pIn;
  152. } else {
  153. *pOut++ = TEXT('_');
  154. }
  155. pIn++;
  156. }
  157. *pOut=TEXT('\0');
  158. }
  159. // Company: MGI Software Corp.
  160. // URL: http://www.dvdmax.com/updates/
  161. //
  162. // Company: Ravisent Technologies
  163. // URL: http://www.ravisentdirect.com/upgrade/dvdup.html
  164. //
  165. // Company: CyberLink Corp.
  166. // URL: http://www.cyberlink.com.tw/english/download/download.asp#upgrade
  167. //
  168. // Company: National Semiconductor Corporation
  169. // URL: http://www.national.com/appinfo/dvd/support/msft/
  170. //
  171. // Company: InterVideo, Inc.
  172. // URL: http:/www.intervideo.com/products/custom/ms/whistler/upgrade.html
  173. //
  174. static void CreateRedirectorString( TCHAR* pWebsite, const DVDResult& result )
  175. {
  176. TCHAR filteredName[2000];
  177. AlphaNumStrCpy( filteredName, result.GetCompanyName() );
  178. // Generate extended information for our redirector site
  179. DecoderVendor vendor = result.GetVendor();
  180. TCHAR pQuery[1000];
  181. wsprintf( pQuery, TEXT("vendorid=%d&version=%08x%08x&crc=%08x&company=%s"),
  182. vendor,
  183. DWORD(result.GetVersion()>>32), DWORD(result.GetVersion() ),
  184. result.GetCRC(),
  185. filteredName);
  186. switch( vendor ) {
  187. case vendor_MediaMatics:
  188. wsprintf( pWebsite, TEXT("www.national.com/appinfo/dvd/support/msft"));
  189. break;
  190. case vendor_Intervideo:
  191. wsprintf( pWebsite, TEXT("www.intervideo.com/products/custom/ms/whistler/upgrade.html") );
  192. break;
  193. case vendor_CyberLink:
  194. wsprintf( pWebsite, TEXT("www.cyberlink.com.tw/english/download/download.asp#upgrade") );
  195. break;
  196. case vendor_Ravisent:
  197. wsprintf( pWebsite, TEXT("www.ravisentdirect.com/upgrade/dvdup.htm") );
  198. break;
  199. case vendor_MGI:
  200. wsprintf( pWebsite, TEXT("www.dvdmax.com/updates") );
  201. break;
  202. default:
  203. wsprintf( pWebsite, TEXT("windowsupdate.microsoft.com/dvdupgrade.asp?%s"), pQuery );
  204. break;
  205. }
  206. }
  207. static bool LaunchURL( const TCHAR* pURL )
  208. {
  209. ULONG uRC = (ULONG)(ULONG_PTR) ShellExecute(NULL, TEXT("open"), pURL, NULL, NULL, SW_SHOWNORMAL);
  210. if ( uRC <= 32 ) {
  211. return false;
  212. } else {
  213. return true;
  214. }
  215. }
  216. static bool CreateDesktopShortcut( const DVDResult& result )
  217. {
  218. TCHAR website[1000];
  219. CreateRedirectorString( website, result );
  220. TCHAR path[MAX_PATH];
  221. DWORD dwLen=sizeof(path);
  222. if( GetAllUsersProfileDirectory( path, &dwLen )) {
  223. lstrcat( path, TEXT("\\desktop\\Upgrade DVD Decoder.url"));
  224. TCHAR url[1000];
  225. wsprintf( url, TEXT("http://%s"), website );
  226. HRESULT hres = CreateShortcutToURL( url, path );
  227. return SUCCEEDED(hres);
  228. } else {
  229. return false;
  230. }
  231. }
  232. static void LaunchUI( const DVDResult& result )
  233. {
  234. TCHAR website[1000];
  235. CreateRedirectorString( website, result );
  236. #if 0
  237. switch( MessageBoxW( NULL,
  238. L"Windows has detected an incompatible software DVD decoder.\n\n"
  239. L"Would you like to upgrade your decoder at this time ?\n\n"
  240. L"Select YES to download an upgrade\n"
  241. L"Select NO to have Windows create a desktop shortcut so that you can upgrade later",
  242. TEXT("DVD Decoder upgrade"),
  243. MB_YESNO ))
  244. {
  245. case IDYES:
  246. if(!LaunchURL( website ) ) {
  247. MessageBox( NULL, TEXT("Could not reach internet site. A shortcut has been created for you to try again later"),
  248. NULL, MB_OK );
  249. }
  250. break;
  251. case IDNO:
  252. CreateDesktopShortcut( result );
  253. DVDDetectSetupRun::Remove();
  254. break;
  255. default:
  256. break;
  257. }
  258. #else
  259. TCHAR url[1000];
  260. wsprintf( url, TEXT("HCP://system/DVDUpgrd/dvdupgrd.htm?website=%s"), website);
  261. LaunchURL( url );
  262. #endif
  263. }
  264. static void DetectForUpgrade( bool fForceUpgrade )
  265. {
  266. DVDDetectBuffer buffer;
  267. const DVDResult* pResult = buffer.Detect();
  268. if( pResult ) {
  269. const DVDResult& result = *pResult;
  270. // map company name groups
  271. bool fShouldUpgrade = (fForceUpgrade || result.ShouldUpgrade() );
  272. if( fShouldUpgrade && (IsUserAdmin() || IsUserPowerUser()) )
  273. {
  274. LaunchUI( result );
  275. }
  276. if(!fShouldUpgrade ) {
  277. // if they don't need to upgrade (sounds like we're running after an upgrade)
  278. //
  279. DVDDetectSetupRun::Remove();
  280. }
  281. }
  282. }
  283. static void DetectForSetup( bool fWillBeUpgrade )
  284. {
  285. DVDDetectBuffer buffer;
  286. const DVDResult* pResult = buffer.Detect();
  287. if( pResult ) {
  288. const DVDResult& result = *pResult;
  289. bool fResult = result.ShouldUpgrade( fWillBeUpgrade );
  290. if( fResult ) {
  291. DBGBOX(MessageBox( NULL, TEXT("DetectDVDForSetup = true, add to setup run"), NULL, MB_OK ));
  292. DVDDetectSetupRun::Add();
  293. } else {
  294. DBGBOX(MessageBox( NULL, TEXT("DetectDVDForSetup = false, not added to setup run"), NULL, MB_OK ));
  295. }
  296. } else {
  297. DBGBOX(MessageBox( NULL, TEXT("DetectDVDForSetup = no decoder detected"), NULL, MB_OK ));
  298. //__asm int 3
  299. const DVDResult* pResult2 = buffer.Detect();
  300. }
  301. }
  302. static void DetectForRemove()
  303. {
  304. DVDDetectBuffer buffer;
  305. const DVDResult* pResult = buffer.Detect();
  306. if( pResult ) {
  307. const DVDResult& result = *pResult;
  308. // Allows create it since we don't know the 9x info anymore
  309. // and this only comes from the PCHealth UI's method
  310. // if( result.ShouldUpgrade())
  311. CreateDesktopShortcut( result );
  312. DVDDetectSetupRun::Remove();
  313. }
  314. }
  315. static void DetectCurrent()
  316. {
  317. DVDDetectBuffer buffer;
  318. TCHAR out[1024];
  319. out[0]=TEXT('\0');
  320. if(SUCCEEDED(buffer.DetectAll()))
  321. {
  322. TCHAR* pOut=out;
  323. if( buffer.mci.Found()) {
  324. pOut = Append(pOut, TEXT("\nMCI:\n"));
  325. pOut = Print(pOut, buffer.mci);
  326. }
  327. if( buffer.hw.Found()) {
  328. pOut = Append(pOut, TEXT("\nDShow HW:\n" ));
  329. pOut = Print(pOut, buffer.hw);
  330. }
  331. if( buffer.sw.Found()) {
  332. pOut = Append(pOut, TEXT("\nDShow SW:\n" ));
  333. pOut = Print(pOut, buffer.sw);
  334. }
  335. if( pOut == out ) {
  336. pOut = Append( pOut, TEXT("No decoders found"));
  337. }
  338. } else {
  339. Append( out, TEXT("DvdCheck Failed\n") );
  340. }
  341. OutputDebugString( out );
  342. MessageBox( NULL, out, TEXT("Detected DVD decoders"), MB_OK );
  343. }
  344. extern "C" BOOL IsDvdPresent (VOID);
  345. int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  346. LPSTR lpCmdLine,
  347. int nCmdShow)
  348. {
  349. if( lpCmdLine ) {
  350. if( AreEquivalent( lpCmdLine, "/setup") ) {
  351. DetectForSetup( false );
  352. } else if( AreEquivalent( lpCmdLine, "/setup98") ) {
  353. DetectForSetup( true );
  354. } else if( AreEquivalent( lpCmdLine, "/upgrade" ) ) {
  355. DetectForUpgrade( false );
  356. } else if( AreEquivalent( lpCmdLine, "/forceupgrade" ) ) {
  357. DetectForUpgrade( true );
  358. } else if( AreEquivalent( lpCmdLine, "/remove" ) ) {
  359. DetectForRemove();
  360. } else if( AreEquivalent( lpCmdLine, "/detect" ) ) {
  361. DetectCurrent();
  362. }
  363. }
  364. return 0;
  365. }