00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "ShareazaURL.h"
00026 #include "Transfer.h"
00027 #include "QuerySearch.h"
00028 #include "DiscoveryServices.h"
00029
00030 #include "TigerTree.h"
00031 #include "SHA.h"
00032 #include "MD5.h"
00033 #include "ED2K.h"
00034 #include "BTInfo.h"
00035
00036 #ifdef _DEBUG
00037 #undef THIS_FILE
00038 static char THIS_FILE[]=__FILE__;
00039 #define new DEBUG_NEW
00040 #endif
00041
00042
00044
00045
00046 CShareazaURL::CShareazaURL()
00047 {
00048 m_pTorrent = NULL;
00049 Clear();
00050 }
00051
00052 CShareazaURL::CShareazaURL(CBTInfo* pTorrent)
00053 {
00054 m_pTorrent = NULL;
00055 Clear();
00056 m_nAction = uriDownload;
00057 m_pTorrent = pTorrent;
00058 m_bBTH = TRUE;
00059 m_pBTH = pTorrent->m_pInfoSHA1;
00060 m_bSHA1 = pTorrent->m_bDataSHA1;
00061 m_pSHA1 = pTorrent->m_pDataSHA1;
00062 m_bED2K = pTorrent->m_bDataED2K;
00063 m_pED2K = pTorrent->m_pDataED2K;
00064 m_bTiger = pTorrent->m_bDataTiger;
00065 m_pTiger = pTorrent->m_pDataTiger;
00066 m_sName = pTorrent->m_sName;
00067 m_bSize = TRUE;
00068 m_nSize = pTorrent->m_nTotalSize;
00069 }
00070
00071 CShareazaURL::~CShareazaURL()
00072 {
00073 Clear();
00074 }
00075
00077
00078
00079 void CShareazaURL::Clear()
00080 {
00081 m_nAction = uriNull;
00082 m_bSHA1 = FALSE;
00083 m_bTiger = FALSE;
00084 m_bMD5 = FALSE;
00085 m_bED2K = FALSE;
00086 m_bBTH = FALSE;
00087 m_bSize = FALSE;
00088 m_nPort = GNUTELLA_DEFAULT_PORT;
00089
00090 if ( m_pTorrent != NULL ) delete m_pTorrent;
00091 m_pTorrent = NULL;
00092 }
00093
00095
00096
00097 BOOL CShareazaURL::Parse(LPCTSTR pszURL)
00098 {
00099 Clear();
00100
00101 if ( _tcsnicmp( pszURL, _T("magnet:?"), 8 ) == 0 )
00102 {
00103 pszURL += 8;
00104 return ParseMagnet( pszURL );
00105 }
00106 else if ( _tcsnicmp( pszURL, _T("shareaza:"), 9 ) == 0 ||
00107 _tcsnicmp( pszURL, _T("gnutella:"), 9 ) == 0 )
00108 {
00109 SkipSlashes( pszURL, 9 );
00110 return ParseShareaza( pszURL );
00111 }
00112 else if ( _tcsnicmp( pszURL, _T("gnet:"), 5 ) == 0 )
00113 {
00114 SkipSlashes( pszURL, 5 );
00115 return ParseShareaza( pszURL );
00116 }
00117 else if ( _tcsnicmp( pszURL, _T("ed2k:"), 5 ) == 0 )
00118 {
00119 SkipSlashes( pszURL, 5 );
00120 return ParseDonkey( pszURL );
00121 }
00122 else if ( _tcsnicmp( pszURL, _T("mp2p:"), 5 ) == 0 )
00123 {
00124 SkipSlashes( pszURL, 5 );
00125 return ParsePiolet( pszURL );
00126 }
00127 else if ( _tcsnicmp( pszURL, _T("http://"), 7 ) == 0 )
00128 {
00129 m_sURL = pszURL;
00130 m_nAction = uriSource;
00131 return TRUE;
00132 }
00133 else if ( _tcsnicmp( pszURL, _T("ftp://"), 6 ) == 0 )
00134 {
00135 m_sURL = pszURL;
00136 m_nAction = uriSource;
00137 return TRUE;
00138 }
00139
00140 return FALSE;
00141 }
00142
00144
00145
00146 BOOL CShareazaURL::ParseMagnet(LPCTSTR pszURL)
00147 {
00148 CString strURL( pszURL );
00149
00150 for ( strURL += '&' ; strURL.GetLength() ; )
00151 {
00152 CString strPart = strURL.SpanExcluding( _T("&") );
00153 strURL = strURL.Mid( strPart.GetLength() + 1 );
00154
00155 int nEquals = strPart.Find( '=' );
00156 if ( nEquals < 0 ) continue;
00157
00158 CString strKey = CTransfer::URLDecode( strPart.Left( nEquals ) );
00159 CString strValue = CTransfer::URLDecode( strPart.Mid( nEquals + 1 ) );
00160
00161 SafeString( strKey );
00162 SafeString( strValue );
00163
00164 if ( strKey.IsEmpty() || strValue.IsEmpty() ) continue;
00165
00166 if ( _tcsicmp( strKey, _T("xt") ) == 0 ||
00167 _tcsicmp( strKey, _T("xs") ) == 0 ||
00168 _tcsicmp( strKey, _T("as") ) == 0 )
00169 {
00170 if ( _tcsnicmp( strValue, _T("urn:"), 4 ) == 0 ||
00171 _tcsnicmp( strValue, _T("sha1:"), 5 ) == 0 ||
00172 _tcsnicmp( strValue, _T("bitprint:"), 9 ) == 0 ||
00173 _tcsnicmp( strValue, _T("tree:tiger:"), 11 ) == 0 ||
00174 _tcsnicmp( strValue, _T("tree:tiger/:"), 12 ) == 0 ||
00175 _tcsnicmp( strValue, _T("tree:tiger/1024:"), 16 ) == 0 ||
00176 _tcsnicmp( strValue, _T("md5:"), 4 ) == 0 ||
00177 _tcsnicmp( strValue, _T("ed2k:"), 5 ) == 0 )
00178 {
00179 m_bSHA1 |= CSHA::HashFromURN( strValue, &m_pSHA1 );
00180 m_bTiger |= CTigerNode::HashFromURN( strValue, &m_pTiger );
00181 m_bMD5 |= CMD5::HashFromURN( strValue, &m_pMD5 );
00182 m_bED2K |= CED2K::HashFromURN( strValue, &m_pED2K );
00183 }
00184 else if ( _tcsnicmp( strValue, _T("http://"), 7 ) == 0 ||
00185 _tcsnicmp( strValue, _T("http%3A//"), 9 ) == 0 ||
00186 _tcsnicmp( strValue, _T("ftp://"), 6 ) == 0 ||
00187 _tcsnicmp( strValue, _T("ftp%3A//"), 8 ) == 0 )
00188 {
00189 Replace( strValue, _T(" "), _T("%20") );
00190 Replace( strValue, _T("p%3A//"), _T("p://") );
00191
00192 if ( _tcsicmp( strKey, _T("xt") ) == 0 )
00193 {
00194 CString strURL = _T("@") + strValue;
00195
00196 if ( m_sURL.GetLength() )
00197 m_sURL = strURL + _T(", ") + m_sURL;
00198 else
00199 m_sURL = strURL;
00200 }
00201 else
00202 {
00203 if ( m_sURL.GetLength() ) m_sURL += _T(", ");
00204 m_sURL += strValue;
00205 }
00206 }
00207 }
00208 else if ( _tcsicmp( strKey, _T("dn") ) == 0 )
00209 {
00210 m_sName = strValue;
00211 }
00212 else if ( _tcsicmp( strKey, _T("kt") ) == 0 )
00213 {
00214 m_sName = strValue;
00215 m_bSHA1 = FALSE;
00216 }
00217 else if ( _tcsicmp( strKey, _T("xl") ) == 0 )
00218 {
00219 QWORD nSize;
00220 if ( ( ! m_bSize ) && ( _stscanf( strValue, _T("%I64i"), &nSize ) == 1 ) && ( nSize > 0 ) )
00221 {
00222 m_nSize = nSize;
00223 m_bSize = TRUE;
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 }
00238
00239 if ( m_bSHA1 || m_bTiger || m_bMD5 || m_bED2K || m_sURL.GetLength() )
00240 {
00241 m_nAction = uriDownload;
00242 return TRUE;
00243 }
00244 else if ( m_sName.GetLength() )
00245 {
00246 m_nAction = uriSearch;
00247 return TRUE;
00248 }
00249
00250 return FALSE;
00251 }
00252
00254
00255
00256 BOOL CShareazaURL::ParseShareaza(LPCTSTR pszURL)
00257 {
00258 int nIP[4];
00259
00260 if ( _stscanf( pszURL, _T("%i.%i.%i.%i"), &nIP[0], &nIP[1], &nIP[2], &nIP[3] ) == 4 )
00261 {
00262 return ParseShareazaHost( pszURL );
00263 }
00264
00265 if ( _tcsnicmp( pszURL, _T("host:"), 5 ) == 0 ||
00266 _tcsnicmp( pszURL, _T("node:"), 5 ) == 0 )
00267 {
00268 return ParseShareazaHost( pszURL + 5 );
00269 }
00270 else if ( _tcsnicmp( pszURL, _T("hub:"), 4 ) == 0 )
00271 {
00272 return ParseShareazaHost( pszURL + 4 );
00273 }
00274 else if ( _tcsnicmp( pszURL, _T("server:"), 7 ) == 0 )
00275 {
00276 return ParseShareazaHost( pszURL + 7 );
00277 }
00278 else if ( _tcsnicmp( pszURL, _T("browse:"), 7 ) == 0 )
00279 {
00280 return ParseShareazaHost( pszURL + 7, TRUE );
00281 }
00282 else if ( _tcsnicmp( pszURL, _T("gwc:"), 4 ) == 0 )
00283 {
00284 return ParseDiscovery( pszURL + 4, CDiscoveryService::dsWebCache );
00285 }
00286 else if ( _tcsnicmp( pszURL, _T("meturl:"), 7 ) == 0 )
00287 {
00288 return ParseDiscovery( pszURL + 7, CDiscoveryService::dsServerMet );
00289 }
00290 else
00291 {
00292 return ParseShareazaFile( pszURL );
00293 }
00294 }
00295
00297
00298
00299 BOOL CShareazaURL::ParseShareazaHost(LPCTSTR pszURL, BOOL bBrowse)
00300 {
00301 m_sName = pszURL;
00302 m_sName = m_sName.SpanExcluding( _T("/\\") );
00303
00304 int nPos = m_sName.Find( ':' );
00305
00306 if ( nPos >= 0 )
00307 {
00308 _stscanf( m_sName.Mid( nPos + 1 ), _T("%i"), &m_nPort );
00309 m_sName = m_sName.Left( nPos );
00310 }
00311
00312 m_sName.TrimLeft();
00313 m_sName.TrimRight();
00314
00315 m_nAction = bBrowse ? uriBrowse : uriHost;
00316
00317 return m_sName.GetLength();
00318 }
00319
00321
00322
00323 BOOL CShareazaURL::ParseShareazaFile(LPCTSTR pszURL)
00324 {
00325 CString strURL( pszURL );
00326
00327 for ( strURL += '/' ; strURL.GetLength() ; )
00328 {
00329 CString strPart = strURL.SpanExcluding( _T("/|") );
00330 strURL = strURL.Mid( strPart.GetLength() + 1 );
00331
00332 strPart.TrimLeft();
00333 strPart.TrimRight();
00334
00335 if ( strPart.IsEmpty() ) continue;
00336
00337 if ( _tcsnicmp( strPart, _T("urn:"), 4 ) == 0 ||
00338 _tcsnicmp( strPart, _T("sha1:"), 5 ) == 0 ||
00339 _tcsnicmp( strPart, _T("bitprint:"), 9 ) == 0 ||
00340 _tcsnicmp( strPart, _T("tree:tiger:"), 11 ) == 0 ||
00341 _tcsnicmp( strPart, _T("tree:tiger/:"), 12 ) == 0 ||
00342 _tcsnicmp( strPart, _T("tree:tiger/1024:"), 16 ) == 0 ||
00343 _tcsnicmp( strPart, _T("md5:"), 4 ) == 0 ||
00344 _tcsnicmp( strPart, _T("ed2k:"), 5 ) == 0 )
00345 {
00346 m_bSHA1 |= CSHA::HashFromURN( strPart, &m_pSHA1 );
00347 m_bTiger |= CTigerNode::HashFromURN( strPart, &m_pTiger );
00348 m_bMD5 |= CMD5::HashFromURN( strPart, &m_pMD5 );
00349 m_bED2K |= CED2K::HashFromURN( strPart, &m_pED2K );
00350 }
00351 else if ( _tcsnicmp( strPart, _T("source:"), 7 ) == 0 )
00352 {
00353 CString strSource = CTransfer::URLDecode( strPart.Mid( 7 ) );
00354 SafeString( strSource );
00355
00356 if ( m_sURL.GetLength() ) m_sURL += ',';
00357 m_sURL += _T("http://");
00358 m_sURL += CTransfer::URLEncode( strSource );
00359 m_sURL += _T("/(^name^)");
00360 }
00361 else if ( _tcsnicmp( strPart, _T("name:"), 5 ) == 0 ||
00362 _tcsnicmp( strPart, _T("file:"), 5 ) == 0 )
00363 {
00364 m_sName = CTransfer::URLDecode( strPart.Mid( 5 ) );
00365 SafeString( m_sName );
00366 }
00367 else if ( _tcschr( strPart, ':' ) == NULL )
00368 {
00369 m_sName = CTransfer::URLDecode( strPart );
00370 SafeString( m_sName );
00371 }
00372 }
00373
00374 if ( m_sURL.GetLength() )
00375 {
00376 if ( m_sName.GetLength() )
00377 {
00378 Replace( m_sURL, _T("(^name^)"), CTransfer::URLEncode( m_sName ) );
00379 Replace( m_sURL, _T("\\"), _T("/") );
00380 }
00381 else
00382 {
00383 m_sURL.Empty();
00384 }
00385 }
00386
00387 if ( m_bSHA1 || m_bTiger || m_bMD5 || m_bED2K || m_sURL.GetLength() )
00388 {
00389 m_nAction = uriDownload;
00390 return TRUE;
00391 }
00392 else if ( m_sName.GetLength() )
00393 {
00394 m_nAction = uriSearch;
00395 return TRUE;
00396 }
00397
00398 return FALSE;
00399 }
00400
00402
00403
00404 BOOL CShareazaURL::ParseDonkey(LPCTSTR pszURL)
00405 {
00406 if ( _tcsnicmp( pszURL, _T("|file|"), 6 ) == 0 )
00407 {
00408 return ParseDonkeyFile( pszURL + 6 );
00409 }
00410 else if ( _tcsnicmp( pszURL, _T("|server|"), 8 ) == 0 )
00411 {
00412 return ParseDonkeyServer( pszURL + 8 );
00413 }
00414 else if ( _tcsnicmp( pszURL, _T("|meturl|"), 8 ) == 0 )
00415 {
00416 return ParseDiscovery( pszURL + 8, CDiscoveryService::dsServerMet );
00417 }
00418 else
00419 {
00420 return FALSE;
00421 }
00422 }
00423
00425
00426
00427 BOOL CShareazaURL::ParseDonkeyFile(LPCTSTR pszURL)
00428 {
00429 CString strURL( pszURL ), strPart;
00430 int nSep;
00431
00432
00433 nSep = strURL.Find( '|' );
00434 if ( nSep < 0 ) return FALSE;
00435 strPart = strURL.Left( nSep );
00436 strURL = strURL.Mid( nSep + 1 );
00437
00438 m_sName = CTransfer::URLDecode( strPart );
00439 SafeString( m_sName );
00440 if ( m_sName.IsEmpty() ) return FALSE;
00441
00442
00443 nSep = strURL.Find( '|' );
00444 if ( nSep < 0 ) return FALSE;
00445 strPart = strURL.Left( nSep );
00446 strURL = strURL.Mid( nSep + 1 );
00447
00448 if ( _stscanf( strPart, _T("%I64i"), &m_nSize ) != 1 ) return FALSE;
00449 m_bSize = TRUE;
00450
00451
00452 nSep = strURL.Find( '|' );
00453 if ( nSep < 0 ) return FALSE;
00454 strPart = strURL.Left( nSep );
00455 strURL = strURL.Mid( nSep + 1 );
00456
00457 m_bED2K = CED2K::HashFromString( strPart, &m_pED2K );
00458
00459
00460 m_nAction = uriDownload;
00461
00462
00463 nSep = strURL.Find( '|' );
00464 if ( nSep < 0 ) return TRUE;
00465 strPart = strURL.Left( nSep );
00466 strURL = strURL.Mid( nSep + 1 );
00467 while ( strPart != _T("/") )
00468 {
00469
00470 if ( _tcsncmp( strPart, _T("h="), 2 ) == 0 )
00471 {
00472
00473
00474 strPart = strPart.Mid( 2 );
00475 }
00476 else if ( _tcsncmp( strPart, _T("s="), 2 ) == 0 )
00477 {
00478
00479
00480 strPart = strPart.Mid( 2 );
00481
00482 if ( m_sURL.GetLength() ) m_sURL += _T(", ");
00483 SafeString( strPart );
00484 m_sURL += strPart;
00485 }
00486 else if ( _tcsncmp( strPart, _T("p="), 2 ) == 0 )
00487 {
00488
00489
00490 strPart = strPart.Mid( 2 );
00491 }
00492
00493
00494 nSep = strURL.Find( '|' );
00495 if ( nSep < 0 ) return TRUE;
00496 strPart = strURL.Left( nSep );
00497 strURL = strURL.Mid( nSep + 1 );
00498
00499 }
00500
00501
00502 nSep = strURL.Find( ',' );
00503 if ( nSep < 0 ) return TRUE;
00504 strPart = strURL.Left( nSep );
00505 strURL = strURL.Mid( nSep + 1 );
00506
00507 if ( _tcsncmp( strPart, _T("sources"), 7 ) != 0 ) return TRUE;
00508
00509 nSep = strURL.Find( ',' );
00510 if ( nSep < 0 ) nSep = strURL.Find( '|' );
00511 if ( nSep < 0 ) return TRUE;
00512 strPart = strURL.Left( nSep );
00513 strURL = strURL.Mid( nSep + 1 );
00514
00515
00516 CString strEDFTP;
00517 strEDFTP.Format( _T("ed2kftp://%s/%s/%I64i/"), strPart, (LPCTSTR)CED2K::HashToString( &m_pED2K ), m_nSize );
00518 SafeString( strEDFTP );
00519 if ( m_sURL.GetLength() ) m_sURL += _T(", ");
00520 m_sURL += strEDFTP;
00521
00522 return TRUE;
00523 }
00524
00525
00526
00527
00529
00530
00531 BOOL CShareazaURL::ParseDonkeyServer(LPCTSTR pszURL)
00532 {
00533 LPCTSTR pszPort = _tcschr( pszURL, '|' );
00534 if ( pszPort == NULL ) return FALSE;
00535
00536 if ( _stscanf( pszPort + 1, _T("%i"), &m_nPort ) != 1 ) return FALSE;
00537
00538 m_sName = pszURL;
00539 m_sName = m_sName.Left( pszPort - pszURL );
00540
00541 m_sName.TrimLeft();
00542 m_sName.TrimRight();
00543 if ( m_sName.IsEmpty() ) return FALSE;
00544
00545 m_nAction = uriDonkeyServer;
00546
00547 return TRUE;
00548 }
00549
00550
00551
00553
00554
00555 BOOL CShareazaURL::ParsePiolet(LPCTSTR pszURL)
00556 {
00557 if ( _tcsnicmp( pszURL, _T("file|"), 5 ) == 0 )
00558 {
00559 return ParsePioletFile( pszURL + 5 );
00560 }
00561 else if ( _tcsnicmp( pszURL, _T("|file|"), 6 ) == 0 )
00562 {
00563 return ParsePioletFile( pszURL + 6 );
00564 }
00565 else
00566 {
00567 return FALSE;
00568 }
00569 }
00570
00572
00573
00574 BOOL CShareazaURL::ParsePioletFile(LPCTSTR pszURL)
00575 {
00576 CString strURL( pszURL ), strPart;
00577 int nSep;
00578
00579 nSep = strURL.Find( '|' );
00580 if ( nSep < 0 ) return FALSE;
00581 strPart = strURL.Left( nSep );
00582 strURL = strURL.Mid( nSep + 1 );
00583
00584 m_sName = CTransfer::URLDecode( strPart );
00585 SafeString( m_sName );
00586 if ( m_sName.IsEmpty() ) return FALSE;
00587
00588 nSep = strURL.Find( '|' );
00589 if ( nSep < 0 ) return FALSE;
00590 strPart = strURL.Left( nSep );
00591 strURL = strURL.Mid( nSep + 1 );
00592
00593 if ( _stscanf( strPart, _T("%I64i"), &m_nSize ) != 1 ) return FALSE;
00594 m_bSize = TRUE;
00595
00596 strPart = strURL.SpanExcluding( _T(" |/") );
00597 m_bSHA1 = CSHA::HashFromString( strPart, &m_pSHA1 );
00598
00599 m_nAction = uriDownload;
00600
00601 return TRUE;
00602 }
00603
00604
00605
00607
00608
00609 BOOL CShareazaURL::ParseDiscovery(LPCTSTR pszURL, int nType)
00610 {
00611 if ( _tcsncmp( pszURL, _T("http://"), 7 ) != 0 &&
00612 _tcsncmp( pszURL, _T("https://"), 8 ) != 0 ) return FALSE;
00613
00614 m_nAction = uriDiscovery;
00615 m_sURL = pszURL;
00616 m_nSize = nType;
00617
00618 return TRUE;
00619 }
00620
00622
00623
00624 void CShareazaURL::SkipSlashes(LPCTSTR& pszURL, int nAdd)
00625 {
00626 pszURL += nAdd;
00627 while ( *pszURL == '/' ) pszURL++;
00628 }
00629
00630 void CShareazaURL::SafeString(CString& strInput)
00631 {
00632 strInput.TrimLeft();
00633 strInput.TrimRight();
00634
00635 for ( int nIndex = 0 ; nIndex < strInput.GetLength() ; nIndex++ )
00636 {
00637 TCHAR nChar = strInput.GetAt( nIndex );
00638 if ( nChar >= 0 && nChar < 32 ) strInput.SetAt( nIndex, '_' );
00639 }
00640 }
00641
00643
00644
00645 CQuerySearch* CShareazaURL::ToQuery()
00646 {
00647 if ( m_nAction != uriDownload && m_nAction != uriSearch ) return FALSE;
00648
00649 CQuerySearch* pSearch = new CQuerySearch();
00650
00651 if ( m_sName.GetLength() )
00652 {
00653 pSearch->m_sSearch = m_sName;
00654 }
00655
00656 if ( m_bSHA1 )
00657 {
00658 pSearch->m_bSHA1 = TRUE;
00659 pSearch->m_pSHA1 = m_pSHA1;
00660 }
00661
00662 if ( m_bED2K )
00663 {
00664 pSearch->m_bED2K = TRUE;
00665 pSearch->m_pED2K = m_pED2K;
00666 }
00667
00668 return pSearch;
00669 }
00670
00672
00673
00674 void CShareazaURL::Register(BOOL bOnStartup)
00675 {
00676 RegisterShellType( _T("shareaza"), _T("URL:Shareaza P2P"), NULL, _T("Shareaza"), _T("URL"), IDR_MAINFRAME );
00677 RegisterMagnetHandler( _T("Shareaza"), _T("Shareaza Peer to Peer"), _T("Shareaza can automatically search for and download the selected content its peer-to-peer networks."), _T("Shareaza"), IDR_MAINFRAME );
00678
00679 if ( Settings.Web.Magnet )
00680 {
00681 RegisterShellType( _T("magnet"), _T("URL:Magnet Protocol"), NULL, _T("Shareaza"), _T("URL"), IDR_MAINFRAME );
00682 }
00683 else
00684 {
00685 UnregisterShellType( _T("magnet") );
00686 }
00687
00688 if ( Settings.Web.Gnutella )
00689 {
00690 RegisterShellType( _T("gnutella"), _T("URL:Gnutella Protocol"), NULL, _T("Shareaza"), _T("URL"), IDR_MAINFRAME );
00691 RegisterShellType( _T("gnet"), _T("URL:Gnutella Protocol"), NULL, _T("Shareaza"), _T("URL"), IDR_MAINFRAME );
00692 }
00693 else
00694 {
00695 UnregisterShellType( _T("gnutella") );
00696 UnregisterShellType( _T("gnet") );
00697 }
00698
00699 if ( Settings.Web.ED2K )
00700 {
00701 RegisterShellType( _T("ed2k"), _T("URL:eDonkey2000 Protocol"), NULL, _T("Shareaza"), _T("URL"), IDR_MAINFRAME );
00702 }
00703 else
00704 {
00705 UnregisterShellType( _T("ed2k") );
00706 }
00707
00708 if ( Settings.Web.Piolet )
00709 {
00710 RegisterShellType( _T("mp2p"), _T("URL:Piolet Protocol"), NULL, _T("Shareaza"), _T("URL"), IDR_MAINFRAME );
00711 }
00712 else
00713 {
00714 UnregisterShellType( _T("mp2p") );
00715 }
00716
00717 if ( ( ! bOnStartup ) || ( ! Settings.Live.FirstRun ) )
00718 {
00719 if ( Settings.Web.Torrent )
00720 {
00721 RegisterShellType( _T("bittorrent"), _T("TORRENT File"), _T(".torrent"),
00722 _T("Shareaza"), _T("TORRENT"), IDR_MAINFRAME );
00723 }
00724 else
00725 {
00726 UnregisterShellType( _T("bittorrent") );
00727 }
00728 }
00729
00730 RegisterShellType( _T("Shareaza.Collection"), _T("Shareaza Collection File"),
00731 _T(".co"), _T("Shareaza"), _T("COLLECTION"), IDI_COLLECTION );
00732
00733 RegisterShellType( _T("Shareaza.Collection"), _T("Shareaza Collection File"),
00734 _T(".collection"), _T("Shareaza"), _T("COLLECTION"), IDI_COLLECTION );
00735 }
00736
00738
00739
00740 BOOL CShareazaURL::RegisterShellType(LPCTSTR pszProtocol, LPCTSTR pszName, LPCTSTR pszType, LPCTSTR pszApplication, LPCTSTR pszTopic, UINT nIDIcon, BOOL bOverwrite)
00741 {
00742 HKEY hKey, hSub1, hSub2, hSub3, hSub4;
00743 CString strProgram, strValue;
00744 DWORD nDisposition;
00745 TCHAR szPath[128];
00746
00747 if ( RegCreateKeyEx( HKEY_CLASSES_ROOT, pszProtocol, 0, NULL, 0,
00748 KEY_ALL_ACCESS, NULL, &hKey, &nDisposition ) ) return FALSE;
00749
00750 if ( nDisposition == REG_OPENED_EXISTING_KEY && ! bOverwrite )
00751 {
00752 RegCloseKey( hKey );
00753 return FALSE;
00754 }
00755
00756 BOOL bProtocol = _tcsncmp( pszName, _T("URL:"), 4 ) == 0;
00757 GetModuleFileName( NULL, szPath, 128 );
00758 strProgram = szPath;
00759
00760 RegSetValueEx( hKey, NULL, 0, REG_SZ, (LPBYTE)pszName, sizeof(TCHAR) * ( _tcslen( pszName ) + 1 ) );
00761
00762 if ( bProtocol )
00763 {
00764 RegSetValueEx( hKey, _T("URL Protocol"), 0, REG_SZ, (LPBYTE)(LPCTSTR)strValue, sizeof(TCHAR) );
00765 }
00766
00767 if ( ! RegCreateKey( hKey, _T("DefaultIcon"), &hSub1 ) )
00768 {
00769 strValue.Format( _T("\"%s\",-%u"), (LPCTSTR)strProgram, nIDIcon );
00770 RegSetValueEx( hSub1, NULL, 0, REG_SZ, (LPBYTE)(LPCTSTR)strValue, sizeof(TCHAR) * ( strValue.GetLength() + 1 ) );
00771 RegCloseKey( hSub1 );
00772 }
00773
00774 if ( ! RegCreateKey( hKey, _T("shell"), &hSub1 ) )
00775 {
00776 if ( ! RegCreateKey( hSub1, _T("open"), &hSub2 ) )
00777 {
00778 if ( ! RegCreateKey( hSub2, _T("command"), &hSub3 ) )
00779 {
00780 strValue.Format( _T("\"%s\" \"%%%c\""), (LPCTSTR)strProgram, bProtocol ? 'L' : '1' );
00781 RegSetValueEx( hSub3, NULL, 0, REG_SZ, (LPBYTE)(LPCTSTR)strValue, sizeof(TCHAR) * ( strValue.GetLength() + 1 ) );
00782 RegCloseKey( hSub3 );
00783 }
00784
00785 if ( ! RegCreateKey( hSub2, _T("ddeexec"), &hSub3 ) )
00786 {
00787 RegSetValueEx( hSub3, NULL, 0, REG_SZ, (LPBYTE)_T("%1"), sizeof(TCHAR) * 3 );
00788
00789 if ( ! RegCreateKey( hSub3, _T("Application"), &hSub4 ) )
00790 {
00791 RegSetValueEx( hSub4, NULL, 0, REG_SZ, (LPBYTE)pszApplication,
00792 sizeof(TCHAR) * ( _tcslen( pszApplication ) + 1 ) );
00793 RegCloseKey( hSub4 );
00794 }
00795
00796 if ( ! RegCreateKey( hSub3, _T("Topic"), &hSub4 ) )
00797 {
00798 RegSetValueEx( hSub4, NULL, 0, REG_SZ, (LPBYTE)pszTopic,
00799 sizeof(TCHAR) * ( _tcslen( pszTopic ) + 1 ) );
00800 RegCloseKey( hSub4 );
00801 }
00802
00803 RegCloseKey( hSub3 );
00804 }
00805
00806 RegCloseKey( hSub2 );
00807 }
00808
00809 RegCloseKey( hSub1 );
00810 }
00811
00812 if ( pszType != NULL && _tcscmp( pszType, _T(".torrent") ) == 0 )
00813 {
00814 BYTE pData[4] = { 0x00, 0x00, 0x01, 0x00 };
00815 RegSetValueEx( hKey, _T("EditFlags"), 0, REG_BINARY, pData, 4 );
00816 }
00817
00818 RegCloseKey( hKey );
00819
00820 if ( pszType != NULL )
00821 {
00822 if ( ! RegCreateKeyEx( HKEY_CLASSES_ROOT, pszType, 0, NULL, 0,
00823 KEY_ALL_ACCESS, NULL, &hKey, &nDisposition ) )
00824 {
00825 RegSetValueEx( hKey, NULL, 0, REG_SZ, (LPBYTE)pszProtocol,
00826 sizeof(TCHAR) * ( _tcslen( pszProtocol ) + 1 ) );
00827 RegCloseKey( hKey );
00828 }
00829 }
00830
00831 return TRUE;
00832 }
00833
00834 BOOL CShareazaURL::IsRegistered(LPCTSTR pszProtocol)
00835 {
00836 HKEY hKey[4];
00837
00838 if ( RegOpenKeyEx( HKEY_CLASSES_ROOT, pszProtocol, 0, KEY_READ, &hKey[0] ) ) return FALSE;
00839
00840 TCHAR szApp[128];
00841 szApp[0] = 0;
00842
00843 if ( RegOpenKeyEx( hKey[0], _T("shell"), 0, KEY_READ, &hKey[1] ) == 0 )
00844 {
00845 if ( RegOpenKeyEx( hKey[1], _T("open"), 0, KEY_READ, &hKey[2] ) == 0 )
00846 {
00847 if ( RegOpenKeyEx( hKey[2], _T("command"), 0, KEY_READ, &hKey[3] ) == 0 )
00848 {
00849 DWORD nType = REG_SZ;
00850 DWORD nApp = sizeof(TCHAR) * 127;
00851 RegQueryValueEx( hKey[3], NULL, NULL, &nType, (LPBYTE)szApp, &nApp );
00852 szApp[ nApp / sizeof(TCHAR) ] = 0;
00853 RegCloseKey( hKey[3] );
00854 }
00855 RegCloseKey( hKey[2] );
00856 }
00857 RegCloseKey( hKey[1] );
00858 }
00859
00860 RegCloseKey( hKey[0] );
00861
00862 TCHAR szPath[128];
00863 GetModuleFileName( NULL, szPath, 128 );
00864
00865 return _tcsistr( szApp, szPath ) != NULL;
00866 }
00867
00868 BOOL CShareazaURL::UnregisterShellType(LPCTSTR pszProtocol)
00869 {
00870 if ( ! IsRegistered( pszProtocol ) ) return FALSE;
00871
00872 DeleteKey( HKEY_CLASSES_ROOT, pszProtocol );
00873 RegDeleteKey( HKEY_CLASSES_ROOT, pszProtocol );
00874
00875 return TRUE;
00876 }
00877
00878 void CShareazaURL::DeleteKey(HKEY hParent, LPCTSTR pszKey)
00879 {
00880 CStringArray pList;
00881 HKEY hKey;
00882
00883 if ( RegOpenKeyEx( hParent, pszKey, 0, KEY_ALL_ACCESS, &hKey ) ) return;
00884
00885 for ( DWORD dwIndex = 0 ; ; dwIndex++ )
00886 {
00887 DWORD dwName = 64 * sizeof(TCHAR);
00888 TCHAR szName[64];
00889
00890 LRESULT lResult = RegEnumKeyEx( hKey, dwIndex, szName, &dwName, NULL, NULL, 0, NULL );
00891 if ( lResult != ERROR_SUCCESS ) break;
00892
00893 szName[ dwName / sizeof(TCHAR) ] = 0;
00894 pList.Add( szName );
00895 DeleteKey( hKey, szName );
00896 }
00897
00898 for ( int nItem = 0 ; nItem < pList.GetSize() ; nItem++ )
00899 {
00900 RegDeleteKey( hKey, pList.GetAt( nItem ) );
00901 }
00902
00903 RegCloseKey( hKey );
00904 }
00905
00907
00908
00909 BOOL CShareazaURL::RegisterMagnetHandler(LPCTSTR pszID, LPCTSTR pszName, LPCTSTR pszDescription, LPCTSTR pszApplication, UINT nIDIcon)
00910 {
00911 HKEY hSoftware, hMagnetRoot, hHandlers, hHandler;
00912 DWORD dwDisposition;
00913 LONG lResult;
00914
00915 lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software"), 0, KEY_ALL_ACCESS,
00916 &hSoftware );
00917
00918 if ( lResult != ERROR_SUCCESS ) return FALSE;
00919
00920 lResult = RegCreateKeyEx( hSoftware, _T("Magnet"), 0, NULL, 0, KEY_ALL_ACCESS,
00921 NULL, &hMagnetRoot, &dwDisposition );
00922
00923 if ( lResult != ERROR_SUCCESS )
00924 {
00925 RegCloseKey( hSoftware );
00926 return FALSE;
00927 }
00928
00929 lResult = RegCreateKeyEx( hMagnetRoot, _T("Handlers"), 0, NULL, 0, KEY_ALL_ACCESS,
00930 NULL, &hHandlers, &dwDisposition );
00931
00932 if ( lResult != ERROR_SUCCESS )
00933 {
00934 RegCloseKey( hMagnetRoot );
00935 RegCloseKey( hSoftware );
00936 return FALSE;
00937 }
00938
00939 lResult = RegCreateKeyEx( hHandlers, pszID, 0, NULL, 0, KEY_ALL_ACCESS,
00940 NULL, &hHandler, &dwDisposition );
00941
00942 if ( lResult != ERROR_SUCCESS )
00943 {
00944 RegCloseKey( hHandler );
00945 RegCloseKey( hMagnetRoot );
00946 RegCloseKey( hSoftware );
00947 return FALSE;
00948 }
00949
00950 CString strAppPath, strIcon, strCommand;
00951 TCHAR szPath[128];
00952
00953 GetModuleFileName( NULL, szPath, 128 );
00954 strAppPath = szPath;
00955
00956 strIcon.Format( _T("\"%s\",-%u"), (LPCTSTR)strAppPath, nIDIcon );
00957 strCommand.Format( _T("\"%s\" \"%%URL\""), (LPCTSTR)strAppPath );
00958
00959 RegSetValueEx( hHandler, _T(""), 0, REG_SZ, (LPBYTE)pszName, sizeof(TCHAR) * ( _tcslen( pszName ) + 1 ) );
00960 RegSetValueEx( hHandler, _T("Description"), 0, REG_SZ,
00961 (LPBYTE)pszDescription, sizeof(TCHAR) * ( _tcslen( pszDescription ) + 1 ) );
00962
00963 RegSetValueEx( hHandler, _T("DefaultIcon"), 0, REG_SZ,
00964 (LPBYTE)(LPCTSTR)strIcon, sizeof(TCHAR) * ( strIcon.GetLength() + 1 ) );
00965
00966 RegSetValueEx( hHandler, _T("ShellExecute"), 0, REG_SZ,
00967 (LPBYTE)(LPCTSTR)strCommand, sizeof(TCHAR) * ( strCommand.GetLength() + 1 ) );
00968
00969 RegSetValueEx( hHandler, _T("DdeApplication"), 0, REG_SZ,
00970 (LPBYTE)pszApplication, sizeof(TCHAR) * ( _tcslen( pszApplication ) + 1 ) );
00971
00972 RegSetValueEx( hHandler, _T("DdeTopic"), 0, REG_SZ, (LPBYTE)_T("URL"), sizeof(TCHAR) * 4 );
00973
00974 RegCloseKey( hHandler );
00975 RegCloseKey( hHandlers );
00976 RegCloseKey( hMagnetRoot );
00977 RegCloseKey( hSoftware );
00978
00979 return TRUE;
00980 }
00981