如果你没用过迅雷看看, 或是不知道XV文件的, …
写了很久了, 但是担心版权问题, 一直没有帖出来~~~
能提取截止目前最新版本的迅雷看看XV文件. 好了, 不多说, 懒得多说.
还是开源吧, 效果图以后补上. 暂时没有需要转换的文件. 🙂
这一版本我忘了写检查磁盘剩余空间的过程, 呃, …
/* tabsize:4 */ #include <stdio.h> #include <string.h> #define _WIN32_WINNT 0x0502 #include <Windows.h> int cntFileProcessed = 0; //count file that processed, accumulated. int scrWidth; //screen width void ResetCursorPosvoid) { CONSOLE_SCREEN_BUFFER_INFO sbi; COORD co; HANDLE hOutput; hOutput = GetStdHandleSTD_OUTPUT_HANDLE); GetConsoleScreenBufferInfohOutput, &sbi); co.X = sbi.dwCursorPosition.X-5+1+4); //e.g.:1024M,100% co.Y = sbi.dwCursorPosition.Y; SetConsoleCursorPositionhOutput, co); //sure to leave hOutput as it was return; } void ExtractFilechar* filespec) { #define BUFSIZE 1<<20)*5) //5M buffer HANDLE hFileIn = NULL; //handle of input file HANDLE hFileOut = NULL; //handle of output file DWORD dwSizeRead = 0; //the ReadFile function Read size DWORD dwSizeWritten = 0;//the WriteFile function Written size DWORD dwSize = 0; int magicNumber = 0; //you may know when you look, I suppose. int fileType = 0; //indicates what file it is LARGE_INTEGER li; //for SetFilePointer function use,2M offset of REAL movie data BYTE hdr[4]; //the *.xv file header BYTE ch; // char* pchar; //tmp use char fileOut[MAX_PATH]; //namely, the output file BYTE* buffer = NULL; //block extraction data, every time it extracts 5MB data at most char* errMsg = NULL; //FormatMessage int lastErr = 0; //GetLastError int percent = 0; //percentage of processed data int readSize = 0; //total size Read DWORD fileSize; //total file size, for percentage use int prtLen; //the printfand its relative) returned int dotLen; //as you see at the screen int k; //I think you know... li.LowPart = 1<<21; li.HighPart = 0; buffer = BYTE*)mallocBUFSIZE); //5M buffer size ifbuffer == NULL) { fprintfstderr, "内存分配失败!\n"); return; } hFileIn = CreateFilefilespec, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); ifhFileIn == INVALID_HANDLE_VALUE) { freebuffer); buffer = NULL; lastErr = GetLastError); ifFormatMessageFORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastErr, MAKELANGIDLANG_NEUTRAL, SUBLANG_NEUTRAL), LPSTR)&errMsg, 1, NULL)) { fprintfstderr, "CreateFile:%s\n%s", filespec, errMsg); LocalFreeHLOCAL)errMsg); errMsg = NULL; } return; } fileSize = GetFileSizehFileIn, NULL); iffileSize <= 0x00200000) { fprintfstderr, "文件大小不正确,不能小于2M.%s)\n", filespec); freebuffer); buffer = NULL; CloseHandlehFileIn); hFileIn = NULL; return; } fileSize -= 0x00200000; //2M offset of REAL Video data SetFilePointerExhFileIn, li, NULL, FILE_BEGIN); if!ReadFilehFileIn, hdr, 4, &dwSizeRead, NULL) || dwSizeRead==0) { lastErr = GetLastError); ifFormatMessageFORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastErr, MAKELANGIDLANG_NEUTRAL, SUBLANG_NEUTRAL), LPSTR)&errMsg, 1, NULL)) { fprintfstderr, "ReadFile:%s\n%s", filespec, errMsg); LocalFreeHLOCAL)errMsg); errMsg = NULL; } CloseHandlehFileIn); hFileIn = NULL; freebuffer); buffer = NULL; return; } magicNumber = 338-hdr[1])&0xFF; ifBYTE)hdr[1]+magicNumber)=='R' && BYTE)hdr[2]+magicNumber)=='M' && BYTE)hdr[3]+magicNumber)=='F') { fileType = 1; goto _go; } magicNumber = 294-hdr[1])&0xFF; ifBYTE)hdr[2]+magicNumber)==178 && BYTE)hdr[3]+magicNumber)==117) { fileType = 2; goto _go; } magicNumber = 332-hdr[1])&0xFF ; ifBYTE)hdr[1]+magicNumber)==76 && BYTE)hdr[2]+magicNumber)==86) { fileType = 3 ; goto _go; } magicNumber=329-hdr[1])&0xFF ; ifBYTE)hdr[1]+magicNumber)==73 && BYTE)hdr[2]+magicNumber)==70 && BYTE)hdr[3]+magicNumber)==70) { fileType = 4 ; goto _go; } magicNumber=256-hdr[1])&0xFF ; if!magicNumber+hdr[2])) { fileType = 5 ; goto _go; } magicNumber=256-hdr[1])&0xFF ; ifBYTE)hdr[2]+magicNumber)==1 && BYTE)hdr[3]+magicNumber)==186) { fileType = 6 ; goto _go; } magicNumber=325-hdr[1])&0xFF ; ifBYTE)hdr[1]+magicNumber)==69 && BYTE)hdr[2]+magicNumber)==223 && BYTE)hdr[3]+magicNumber)==163) { fileType = 7 ; goto _go; } fprintfstderr, "不能识别的文件格式!%s)\n", filespec); freebuffer); buffer = NULL; CloseHandlehFileIn); hFileIn = NULL; return; _go: ch = 0; pchar = strrchrfilespec,'\\'); if!pchar) pchar = strrchrfilespec, '/'); pchar = pchar==NULL?filespec:pchar+1; switchfileType) { case 1://rm/rmvb ch = 46; sprintffileOut, "%s%s", pchar, ".rmvb"); break; case 2://wmv ch = 48; sprintffileOut, "%s%s", pchar, ".wmv"); break; case 3://flv ch = 70; sprintffileOut, "%s%s", pchar, ".flv"); break; case 4://avi ch = 82; sprintffileOut, "%s%s", pchar, ".avi"); break; case 5://mp4 ch = 0; sprintffileOut, "%s%s", pchar, ".mp4"); break; case 6://mpeg ch = 0; sprintffileOut, "%s%s", pchar, ".mpeg"); break; case 7://mkv ch = 26; sprintffileOut, "%s%s", pchar, ".mkv"); break; default: break; } hFileOut = CreateFilefileOut, GENERIC_WRITE, FILE_SHARE_READ, NULL, /*CREATE_ALWAYS*/CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); ifhFileOut == INVALID_HANDLE_VALUE) { lastErr = GetLastError); ifFormatMessageFORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastErr, MAKELANGIDLANG_NEUTRAL, SUBLANG_NEUTRAL), LPSTR)&errMsg, 1, NULL)) { fprintfstderr, "CreateFile:%s\n%s", fileOut, errMsg); LocalFreeHLOCAL)errMsg); errMsg = NULL; } CloseHandlehFileIn); hFileIn = NULL; freebuffer); buffer = NULL; return; } WriteFilehFileOut, LPVOID)&ch, 1, &dwSizeWritten, NULL); //handle file header fork = 1; k < 4; k++) hdr[k] = BYTE)hdr[k]+magicNumber)&0xFF); WriteFilehFileOut, &hdr[1], 3, &dwSizeWritten, NULL); //handle encrypted data. is it simple? ReadFilehFileIn, buffer, 1019, &dwSizeRead, NULL); fork=0; k<1019; k++) buffer[k] = BYTE)buffer[k]+magicNumber & 0xFF); WriteFilehFileOut, buffer, 1019, &dwSizeWritten, NULL); readSize += 1024; prtLen = printf"%s%s)", filespec, strrchrfileOut, '.')); dotLen = scrWidth-prtLen%scrWidth; ifdotLen<=10) dotLen += scrWidth; dotLen -= 1; whiledotLen--) printf"."); //it looks like this: left edge-->|mymov.xv.flv).............1024M, 99% | <--right edge //copy rest file, original :-), and show sth. useful. how smart thunder kankan was. whileReadFilehFileIn, buffer, BUFSIZE, &dwSizeRead, NULL) && dwSizeRead != 0) { WriteFilehFileOut, buffer, dwSizeRead, &dwSizeWritten, NULL); readSize += dwSizeRead; ResetCursorPos); printf"%4dM,%3d%%", int)readSize/1<<20)), int)readSize/float)fileSize*100)); } printf"\n"); CloseHandlehFileIn); CloseHandlehFileOut); hFileIn = NULL; hFileOut = NULL; freebuffer); buffer = NULL; cntFileProcessed++; return; } //parse if there to be a wild char void HandleFilechar* filespec) { WIN32_FIND_DATA fd; HANDLE hFile = NULL; char findpath[260]; char tmppath[260]; char* pchar = NULL; hFile = FindFirstFilefilespec, &fd); ifhFile == INVALID_HANDLE_VALUE) { fprintfstderr, "没有文件用于处理!\n"); return; } strncpyfindpath, filespec, sizeoffindpath)); //we need to add a full current path to the dest file //since the fd.cFileName member does not include the path pchar = strrchrfindpath, '\\'); if!pchar) pchar = strrchrfindpath, '/'); //sometimes, it's not back-slash-ed. ifpchar) *pchar+1) = '\0'; do { if!fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) //eliminate directory { ifpchar) { sprintftmppath, "%s%s", findpath, fd.cFileName); //now it's full path ExtractFiletmppath); } else { ExtractFilefd.cFileName); //in current dir } } } while FindNextFilehFile, &fd)); //continue deep search FindClosehFile); hFile = NULL; return; } void Usagechar* name) { char* ptr = strrchrname, '\\'); //only the name we need, not the full path char* pmsg = "迅雷看看XV文件提取器 - 版本:1.0\n" "作者:女孩不哭 编译时间:" __DATE__ " " __TIME__ "\n\n" "使用方法:\"%s /y 文件\", 输出文件在当前工作目录下\n\n" "敬告:迅雷XV文件包含受版权保护的内容.\n" "本程序仅供研究和学习使用, 请自觉将提取的文件立即删除.\n" "切勿将本程序及其提取的文件使用于任何其它用途.\n" "对于使用本程序造成的任何后果, 由使用者自行承担法律责任!\n" "要接受此协议, 请从命令行传入/y作为第1个参数, 文件作为第2个参数.\n"; if!ptr) ptr = strrchrname, '/'); if!ptr) //the cur dir is just in the exe dir ptr = name-1;//ptr+1 printfpmsg, ptr+1); return; } int mainint argc, char** argv) { CONSOLE_SCREEN_BUFFER_INFO sbi; ifargc!=3 || stricmpargv[1], "/y")) //xve /y file format expected { Usageargv[0]); return 1; } GetConsoleScreenBufferInfoGetStdHandleSTD_OUTPUT_HANDLE), &sbi); scrWidth = sbi.dwSize.X; //width, in characters HandleFileargv[2]); //enum files if a wild char is detected printf"处理了 %d 个文件!\n", cntFileProcessed); return 0; }
项目及bin下载:
http://alioss.twofei.com/windows/xve.7z
https://files.cnblogs.com/nbsofer/xve.7z
女孩不哭 @ 2012-08-18 23:37:03 @ http://www.cnblogs.com/nbsofer
PS:
其实我对迅雷看看没一点兴趣…
不过, 从XV文件看来, 迅雷很聪明~~~ 那个聪明, 你懂的.
2013-06-09测试, 仍然能用