Update to use new method of passing password

With later versions of libunrar the method used to supply the password to an archive through the callback changed. Previously you called RARSetPassword, however that does not work with header passwords, so they came up with a different approach. The library passes the address of a wchar character buffer and its size as parameterOne and parameterTwo, and you need to copy the password string into that buffer.
This commit is contained in:
Robert McGovern 2021-05-26 13:49:40 +01:00
parent e1707a7d1c
commit 0cffe85ce5
1 changed files with 43 additions and 6 deletions

View File

@ -8,8 +8,11 @@
#import <Carbon/Carbon.h> #import <Carbon/Carbon.h>
//#import <Growl/Growl.h> //#import <Growl/Growl.h>
#import <UnrarKit/UnrarKit.h>
#import "QuietUnrarAppDelegate.h" #import "QuietUnrarAppDelegate.h"
#import "libunrar/dll.hpp" #import "libunrar/dll.hpp"
#import "libunrar/rardefs.hpp"
#import <wchar.h>
#pragma mark Callbacks #pragma mark Callbacks
// Declartions that are not to be part of the public interface. // Declartions that are not to be part of the public interface.
@ -33,6 +36,8 @@ int callbackFunction(UINT message, LPARAM userData, LPARAM parameterOne, LPARAM
int changeVolume(char * volumeName, int mode) { int changeVolume(char * volumeName, int mode) {
if (mode == RAR_VOL_ASK) if (mode == RAR_VOL_ASK)
[(QuietUnrarAppDelegate *) quietUnrar alertUserOfMissing:volumeName]; [(QuietUnrarAppDelegate *) quietUnrar alertUserOfMissing:volumeName];
return 0;
} }
// Multipurpose callback function that is called un changing a volume, when data is being processed // Multipurpose callback function that is called un changing a volume, when data is being processed
@ -48,11 +53,43 @@ int changeVolume(char * volumeName, int mode) {
// //
// parameterOne & parameterTwo have different meanings depending on what message is passed. // parameterOne & parameterTwo have different meanings depending on what message is passed.
int callbackFunction(UINT message, LPARAM userData, LPARAM parameterOne, LPARAM parameterTwo) { int callbackFunction(UINT message, LPARAM userData, LPARAM parameterOne, LPARAM parameterTwo) {
if (message == UCM_NEEDPASSWORD) { if (message == UCM_NEEDPASSWORDW) {
NSString * password = [(QuietUnrarAppDelegate *) quietUnrar requestArchivePassword]; NSString * password = [(QuietUnrarAppDelegate *) quietUnrar requestArchivePassword];
if (password)
RARSetPassword((HANDLE)userData, (char *) [password cStringUsingEncoding:NSISOLatin1StringEncoding]); if (password) {
} wchar_t const *passwordAsWChar = (const wchar_t *)[password cStringUsingEncoding:NSUTF32LittleEndianStringEncoding];
wcscpy((wchar_t *) parameterOne, passwordAsWChar);
return 1;
} else {
return -1;
}
}
return 0;
/*
You need to copy the password string to buffer with P1 address
and P2 size.
This password string must use little endian Unicode encoding in case
UCM_NEEDPASSWORDW message. Namely, it must be wchar_t and not UTF-8.
case UCM_NEEDPASSWORDW:
{
wchar_t *eol;
printf("\nPassword required: ");
// fgetws may fail to read non-English characters from stdin
// in some compilers. In this case use something more appropriate
// for Unicode input.
fgetws((wchar_t *)P1,(int)P2,stdin);
eol=wcspbrk((wchar_t *)P1,L"\r\n");
if (eol!=NULL)
*eol=0;
}
return(1);
*/
} }
#pragma mark #pragma mark
@ -129,7 +166,7 @@ int callbackFunction(UINT message, LPARAM userData, LPARAM parameterOne, LPARAM
RARSetChangeVolProc(archive, &changeVolume); RARSetChangeVolProc(archive, &changeVolume);
RARSetCallback(archive, &callbackFunction, (LPARAM)archive); RARSetCallback(archive, &callbackFunction, (LPARAM)archive);
while (RARReadHeader(archive, &headerData) != ERAR_END_ARCHIVE) { while (RARReadHeader(archive, &headerData) == ERAR_SUCCESS) {
//NSLog(@"Attempting to extract %s to %@", headerData.FileName, folderToExtractTo); //NSLog(@"Attempting to extract %s to %@", headerData.FileName, folderToExtractTo);
int processResult = 0; int processResult = 0;