📄 decss.cpp
字号:
// DeCSS.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#include <commctrl.h>
#include <shlobj.h>
#include "css/CSSkeysNT.h"
#include "css/CSSscramble.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE g_hInst; // current instance
int iDrive; // drive
BOOL bKeyReceived; // did we successfully get the key?
HWND g_hWnd; // main window
HWND g_hWndDrives; // list of cd-/dvdroms
HWND g_hWndStatus; // status window
HWND g_hWndSector; // sector
HWND g_hWndFiles; // files
HWND g_hWndTransfer; // transfer button
CHAR g_szFolder[MAX_PATH]; // folder to place files
TCHAR g_szTitle[] = "DeCSS by MoRE"; // The title bar text
TCHAR g_szWindowClass[] = "DECSS"; // The title bar text
HANDLE hTransferThread;
BYTE diskkey[6];
BYTE titlekey[6];
int __stdcall WndProc(HWND, UINT, WPARAM, LPARAM);
int TransferFile(LPVOID);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
INITCOMMONCONTROLSEX icc;
g_hInst = hInstance;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_BAR_CLASSES |
ICC_TAB_CLASSES | ICC_UPDOWN_CLASS | ICC_PROGRESS_CLASS |
ICC_HOTKEY_CLASS | ICC_ANIMATE_CLASS | ICC_WIN95_CLASSES |
ICC_DATE_CLASSES | ICC_USEREX_CLASSES | ICC_COOL_CLASSES |
ICC_INTERNET_CLASSES | ICC_PAGESCROLLER_CLASS | ICC_NATIVEFNTCTL_CLASS;
InitCommonControlsEx(&icc);
return(DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_DECSS), 0, &WndProc, 0));
}
void AddFilesToComboBox(int iDrive)
{
CHAR szTemp[MAX_PATH];
HANDLE hSearch;
COMBOBOXEXITEM ci;
WIN32_FIND_DATA findData;
wsprintf(szTemp, "%c:\\VIDEO_TS\\V*", iDrive);
ci.mask = CBEIF_TEXT;
ci.iItem = -1;
ci.pszText = findData.cFileName;
SendMessage(g_hWndFiles, CB_RESETCONTENT, 0, 0);
hSearch = FindFirstFile(szTemp, &findData);
SendMessage(g_hWndFiles, CBEM_INSERTITEMA, 0, (LPARAM) &ci);
while(FindNextFile(hSearch, &findData))
{
SendMessage(g_hWndFiles, CBEM_INSERTITEMA, 0, (LPARAM) &ci);
}
}
void UpdateStatusWindow(LPSTR szString)
{
char curText[2048];
SendMessage(g_hWndStatus, WM_GETTEXT, 2048, (LPARAM) curText);
strcat(curText, szString);
strcat(curText, "\r\n");
SendMessage(g_hWndStatus, WM_SETTEXT, 0, (LPARAM) curText);
SendMessage(g_hWndStatus, EM_LINESCROLL, 0, SendMessage(g_hWndStatus, EM_GETLINECOUNT, 0, 0));
}
int __stdcall WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
COMBOBOXEXITEM ci;
CHAR szVolume[MAX_PATH];
CHAR szTemp[MAX_PATH];
HANDLE hFile;
TCHAR szLastDrive[] = "C:\\";
switch (message)
{
case WM_INITDIALOG:
g_hWndDrives = GetDlgItem(hWnd, IDC_DRIVES);
g_hWndStatus = GetDlgItem(hWnd, IDC_STATUS);
g_hWndSector = GetDlgItem(hWnd, IDC_SECTOR);
g_hWndFiles = GetDlgItem(hWnd, IDC_FILES);
g_hWndTransfer = GetDlgItem(hWnd, IDC_TRANSFER);
ci.mask = CBEIF_TEXT;
ci.iItem = -1;
ci.pszText = szTemp;
for(szLastDrive[0] = 'C'; szLastDrive[0] != 'Z'; szLastDrive[0]++)
{
if(GetDriveType(szLastDrive) == DRIVE_CDROM)
{
szVolume[0] = 0;
GetVolumeInformation(szLastDrive, szVolume, MAX_PATH, 0, 0, 0, 0, 0);
wsprintf(szTemp, "%s [%s]", szLastDrive, szVolume);
SendMessage(g_hWndDrives, CBEM_INSERTITEMA, 0, (LPARAM) &ci);
wsprintf(szTemp, "%c:\\VIDEO_TS\\VIDEO_TS.IFO", szLastDrive[0]);
hFile = CreateFile(szTemp, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hFile != INVALID_HANDLE_VALUE)
{
SendMessage(g_hWndDrives, CB_SETCURSEL, SendMessage(g_hWndDrives, CB_GETCOUNT, 0, 0) - 1, 0);
CloseHandle(hFile);
}
}
}
SendMessage(g_hWndSector, WM_SETTEXT, 0, (LPARAM) "Enter Sector");
return 0;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_GETKEYS:
{
int lba = GetDlgItemInt(hWnd, IDC_SECTOR, 0, TRUE);
int drive = SendMessage(g_hWndDrives, CB_GETCURSEL, 0, 0);
SendMessage(g_hWndDrives, CB_GETLBTEXT, drive, (LPARAM) szTemp);
iDrive = szTemp[0];
bKeyReceived = FALSE;
if(CSSgetdiskkey(iDrive, diskkey))
{
UpdateStatusWindow("Error getting disk key");
break;
}
wsprintf(szTemp, "Disk Key: %02X%02X%02X%02X%02X", diskkey[0], diskkey[1], diskkey[2], diskkey[3], diskkey[4]);
UpdateStatusWindow(szTemp);
if(CSSgettitlekey(iDrive, lba, titlekey))
{
wsprintf(szTemp, "Error getting title key for LBA %08X", lba);
UpdateStatusWindow(szTemp);
}
wsprintf(szTemp, "Title key: %02X%02X%02X%02X%02X", titlekey[0], titlekey[1], titlekey[2], titlekey[3], titlekey[4]);
UpdateStatusWindow(szTemp);
CSSdecrypttitlekey(titlekey, diskkey);
wsprintf(szTemp, "Master key: %02X%02X%02X%02X%02X", titlekey[0], titlekey[1], titlekey[2], titlekey[3], titlekey[4]);
UpdateStatusWindow(szTemp);
bKeyReceived = TRUE;
AddFilesToComboBox(iDrive);
}
break;
case IDC_FOLDER:
{
BROWSEINFO bi;
LPITEMIDLIST pidl;
bi.hwndOwner = hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = szTemp;
bi.lpszTitle = "Locate folder where you want the files to be placed...";
bi.ulFlags = BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
bi.lParam = 0;
pidl = SHBrowseForFolder(&bi);
if(!pidl)
{
MessageBox(hWnd, "You didn't locate a folder!\r\nPlease do so before trying to transfer.", "DeCSS (MoRE)", 0);
break;
}
SHGetPathFromIDList(pidl, g_szFolder);
int iLen = lstrlen(g_szFolder) - 1;
if(g_szFolder[iLen] == '\\')
g_szFolder[iLen] = 0;
}
break;
case IDC_TRANSFER:
{
DWORD dwExitCode;
GetExitCodeThread(hTransferThread, &dwExitCode);
if(dwExitCode == STILL_ACTIVE)
{
hTransferThread = 0;
}
else
{
DWORD threadID;
hTransferThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) TransferFile, 0, 0, &threadID);
}
}
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, 0);
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return 0;
}
int TransferFile(LPVOID Param)
{
HANDLE in, out;
ULONGLONG pos = 0;
BYTE buf[0x800];
DWORD sec = 0, esec = 0, r, w;
CHAR szDecryptFile[MAX_PATH];
CHAR szOutputFile[MAX_PATH];
CHAR szBuffer[MAX_PATH];
CHAR szCurText[2048];
CHAR szBytes[MAX_PATH];
int iLen;
if(bKeyReceived == FALSE)
{
MessageBox(g_hWnd, "Master key has not been retrieved!", "DeCSS (MoRE)", 0);
return 0;
}
if(g_szFolder[0] == 0)
{
MessageBox(g_hWnd, "Please locate a folder before transferring.", "DeCSS (MoRE)", 0);
return 0;
}
SendMessage(g_hWndFiles, CB_GETLBTEXT, SendMessage(g_hWndFiles, CB_GETCURSEL, 0, 0), (LPARAM) szBuffer);
wsprintf(szDecryptFile, "%c:\\VIDEO_TS\\%s", iDrive, szBuffer);
wsprintf(szOutputFile, "%s\\%s", g_szFolder, szBuffer);
iLen = lstrlen(szBuffer) - 1;
if(szBuffer[iLen - 2] != 'V' && szBuffer[iLen - 1] != 'O' && szBuffer[iLen] != 'B')
{
CopyFile(szDecryptFile, szOutputFile, FALSE);
wsprintf(szDecryptFile, "%s was copied", szBuffer);
UpdateStatusWindow(szDecryptFile);
hTransferThread = 0;
return TRUE;
}
in = CreateFile(szDecryptFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if(in == INVALID_HANDLE_VALUE)
{
wsprintf(szOutputFile, "Unable to open %s for reading", szBuffer);
UpdateStatusWindow(szOutputFile);
return 0;
}
out = CreateFile(szOutputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if(out==INVALID_HANDLE_VALUE)
{
wsprintf(szDecryptFile, "Unable to open %s for writing", szOutputFile);
UpdateStatusWindow(szDecryptFile);
CloseHandle(in);
return 0;
}
SendMessage(g_hWndStatus, WM_GETTEXT, 2048, (LPARAM) szCurText);
SendMessage(g_hWndTransfer, WM_SETTEXT, 0, (LPARAM) "Abort");
do
{
ReadFile(in, buf, 0x800, &r, NULL);
if(r != 0x800)
break;
sec++;
if(buf[0x14]&0x30)
{
esec++;
CSSdescramble(buf, titlekey);
buf[0x14] &= 0xcf;
}
WriteFile(out, buf, 0x800, &w, NULL);
if(w != 0x800)
{
wsprintf(szBuffer, "Error writing to %s", szOutputFile);
UpdateStatusWindow(szBuffer);
break;
}
if(!(pos & 0xfffff))
{
lstrcpy(szBuffer, szCurText);
wsprintf(szBytes, "%u bytes transferred", pos);
strcat(szBuffer, szBytes);
strcat(szBuffer, "\r\n");
SendMessage(g_hWndStatus, WM_SETTEXT, 0, (LPARAM) szBuffer);
SendMessage(g_hWndStatus, EM_LINESCROLL, 0, SendMessage(g_hWndStatus, EM_GETLINECOUNT, 0, 0));
}
pos += 0x800;
} while(r == 0x800 && hTransferThread);
if(!hTransferThread)
UpdateStatusWindow("Decryption aborted by user");
wsprintf(szBuffer, "Decrypted %u/%u sectors", esec, sec);
UpdateStatusWindow(szBuffer);
CloseHandle(in);
CloseHandle(out);
SendMessage(g_hWndTransfer, WM_SETTEXT, 0, (LPARAM) "Transfer");
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -