Skip to content

Several error fixes #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 66 additions & 19 deletions fileio.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@

#include "fileio.h"

#define DEBUG 1

void SkylanderIO::fprinthex(FILE *f, unsigned char *c, unsigned int n) {
unsigned int h,i;
unsigned char j;
Expand Down Expand Up @@ -62,9 +60,6 @@ void SkylanderIO::initWithEncryptedFile(char * name) throw (int)

void SkylanderIO::initWithPortal(int number) throw (int) {

#if DEBUG
printf(">>> SkylanderIO::initWithPortal\n");
#endif

if (!sky) {
//printf("Reading Skylander from portal.\n");
Expand All @@ -74,17 +69,24 @@ printf(">>> SkylanderIO::initWithPortal\n");
// printf("\nSkylander read from portal.\n");

}
#if DEBUG
printf("<<< SkylanderIO::initWithPortal\n");
#endif
}


void SkylanderIO::initRawReadPortal(int number) throw (int) {


if (!sky) {
//printf("Reading Skylander from portal.\n");
ReadPortal(buffer,number);
sky = new Skylander(buffer);
// printf("\nSkylander read from portal.\n");

}
}

void SkylanderIO::ReadPortal(unsigned char *s, int number) throw (int)
{

#if DEBUG
printf(">>> SkylanderIO::ReadPortal\n");
#endif
unsigned char data[0x10];
unsigned char *ptr;

Expand All @@ -108,15 +110,11 @@ printf(">>> SkylanderIO::ReadPortal\n");
}

delete port;
#if DEBUG
printf("<<< SkylanderIO::ReadPortal\n");
#endif
}

bool SkylanderIO::writeSkylanderToPortal(int number) throw (int)
{
bool bResult;
bool bNewSkylander = false;
unsigned char data[0x10];

unsigned char old[1024];
Expand Down Expand Up @@ -155,7 +153,7 @@ bool SkylanderIO::writeSkylanderToPortal(int number) throw (int)
if(crypt.IsAccessControlBlock(block) == selectAccessControlBlock) {
changed = (memcmp(old + offset, skydata+offset,BLOCK_SIZE) != 0);
if(changed) {
port->WriteBlock( block, skydata+offset, bNewSkylander);
port->WriteBlock( block, skydata+offset, number);
}
}
}
Expand All @@ -167,12 +165,61 @@ bool SkylanderIO::writeSkylanderToPortal(int number) throw (int)
}


bool SkylanderIO::RawWriteSkylanderToPortal(int number) throw (int)
{
bool bResult;
unsigned char data[0x10];

unsigned char old[1024];
unsigned char skydata[1024];

Crypt crypt;

if (sky) {

PortalIO *port;

ReadPortal(old,number);

memcpy (skydata,sky->getData(),1024);

printf("\nWriting Skylander to portal.\n");

port = new PortalIO();


for(int i=0; i<2; i++) {
// two pass write
// write the access control blocks first
bool selectAccessControlBlock;
if(i == 0) {
selectAccessControlBlock = 1;
} else {
selectAccessControlBlock = 0;
}

for(int block=0; block < 0x40; ++block) {
bool changed, OK;
int offset = block * BLOCK_SIZE;
if(crypt.IsAccessControlBlock(block) == selectAccessControlBlock) {
changed = (memcmp(old + offset, skydata+offset,BLOCK_SIZE) != 0);
if(changed) {
port->WriteBlock( block, skydata+offset, number);
}
}
}
}

return true;
}
return false;
}

bool SkylanderIO::writeSkylanderToUnencryptedFile(char *name) throw (int)
{
if (sky) {
WriteSkylanderFile(name,sky->getData());
}
return true;
}

bool SkylanderIO::writeSkylanderToEncryptedFile(char *name) throw (int)
Expand All @@ -184,7 +231,6 @@ bool SkylanderIO::writeSkylanderToEncryptedFile(char *name) throw (int)
EncryptBuffer(skydata);
WriteSkylanderFile(name,skydata);
}
return true;

}

Expand Down Expand Up @@ -279,7 +325,7 @@ void SkylanderIO::listSkylanders() {
Skylander *sky;
unsigned char data[0x10];


port = new PortalIO();
sky = new Skylander(buffer);

Expand All @@ -288,6 +334,7 @@ void SkylanderIO::listSkylanders() {
{
memset(data,0,0x10);
// must start with a read of block zero

port->ReadBlock(1, data, s);

printf("%0d: %s\n",s,sky->toyName(data[0] + data[1] * 0x100));
Expand Down
4 changes: 3 additions & 1 deletion fileio.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class SkylanderIO {
void initWithUnencryptedFile(char *) throw (int);
void initWithEncryptedFile(char *) throw (int);
void initWithPortal(int) throw (int);
void initRawReadPortal(int) throw (int);

void listSkylanders();

Expand All @@ -31,6 +32,7 @@ class SkylanderIO {
// void setSkylander(Skylander *);

bool writeSkylanderToPortal(int) throw (int);
bool RawWriteSkylanderToPortal(int) throw (int);
bool writeSkylanderToUnencryptedFile(char *) throw (int);
bool writeSkylanderToEncryptedFile(char *) throw (int);

Expand All @@ -57,4 +59,4 @@ class SkylanderIO {
void EncryptBuffer(unsigned char* );
void DecryptBuffer(unsigned char* );

};
};
36 changes: 29 additions & 7 deletions hid_win.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ extern "C" {
typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
typedef BOOLEAN (__stdcall *HidD_SetOutputReport_)(HANDLE handle, PVOID data, ULONG length);
typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
Expand All @@ -112,6 +113,7 @@ extern "C" {
static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
static HidD_GetManufacturerString_ HidD_GetManufacturerString;
static HidD_GetProductString_ HidD_GetProductString;
static HidD_SetOutputReport_ HidD_SetOutputReport;
static HidD_SetFeature_ HidD_SetFeature;
static HidD_GetFeature_ HidD_GetFeature;
static HidD_GetIndexedString_ HidD_GetIndexedString;
Expand Down Expand Up @@ -202,7 +204,7 @@ static int lookup_functions()
RESOLVE(HidD_GetSerialNumberString);
RESOLVE(HidD_GetManufacturerString);
RESOLVE(HidD_GetProductString);
RESOLVE(HidD_SetFeature);
RESOLVE(HidD_SetOutputReport);
RESOLVE(HidD_GetFeature);
RESOLVE(HidD_GetIndexedString);
RESOLVE(HidD_GetPreparsedData);
Expand Down Expand Up @@ -605,7 +607,7 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *
{
DWORD bytes_written;
BOOL res;

int wError;
OVERLAPPED ol;
unsigned char *buf;
memset(&ol, 0, sizeof(ol));
Expand All @@ -627,23 +629,31 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *
memset(buf + length, 0, dev->output_report_length - length);
length = dev->output_report_length;
}

res = WriteFile(dev->device_handle, buf, length, NULL, &ol);



res = WriteFile(dev->device_handle, buf, length, NULL, &ol);
if (!res) {
if (GetLastError() != ERROR_IO_PENDING) {
wError = GetLastError();
printf("%i\n", wError);
if (wError != ERROR_IO_PENDING) {
/* WriteFile() failed. Return error. */
register_error(dev, "WriteFile");
bytes_written = -1;
goto end_of_function;
}
}



/* Wait here until the write is done. This makes
hid_write() synchronous. */
res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/);

res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE);

if (!res) {
/* The Write operation failed. */
wError = GetLastError();
printf("%i", wError);
register_error(dev, "WriteFile");
bytes_written = -1;
goto end_of_function;
Expand Down Expand Up @@ -739,6 +749,18 @@ int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonbloc
return 0; /* Success */
}


int HID_API_EXPORT HID_API_CALL hid_set_output_report(hid_device *dev, const unsigned char *data, size_t length)
{
BOOL res = HidD_SetOutputReport(dev->device_handle, (PVOID)data, length);
if (!res) {
register_error(dev, "HidD_SetOutputReport");
return -1;
}

return length;
}

int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
{
BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, length);
Expand Down
2 changes: 2 additions & 0 deletions hidapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ extern "C" {
This function returns the actual number of bytes written and
-1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_set_output_report(hid_device *device, const unsigned char *data, size_t length);

int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length);

/** @brief Get a feature report from a HID device.
Expand Down
29 changes: 19 additions & 10 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ void usage()
"Reading/Writing:\n"
"-i <file>\tread skylander data from file, with option to decrypt the data.\n"
"-p\t\tread skylander data from portal and decrypt the data.\n"
"-K\t\tread skylander data from portal without decrypting\n"
"-s <skylander> select which skylander.\n"
"-d\t\tdecrypt the data read from the file.\n"
"-o <file>\twrite skylander data to <filename>.\n"
"-a\t\twrite skylander data to automatic filename.\n"
"-W\t\twrite skylander data without encrypting\n"
"-P\t\tencrypt and write skylander data to the portal.\n"
"-e\t\tencrypt data when writing file.\n"
"-D\t\tdump the data of a skylander to the display.\n"
Expand Down Expand Up @@ -68,11 +70,11 @@ int main(int argc, char* argv[])
unsigned char *buffer, *original_data;
bool OK, OK2;

bool encrypt,decrypt,portalIn,portalOut,dump,upgrade,flash,list,autoFile;
bool encrypt,decrypt,portalIn,portalOut,dump,upgrade,flash,list,autoFile,RawWrite,RawRead;

char * inFile, *outFile;

const static char *legal_flags = "alFePpcDo:i:dM:X:H:C:L:R:s:";
const static char *legal_flags = "alFWePpKcDo:i:dM:X:H:C:L:R:s:";

encrypt = false;
decrypt = false;
Expand All @@ -85,6 +87,8 @@ int main(int argc, char* argv[])
flash = false;
list = false;
autoFile = false;
RawWrite = false;
RawRead = false;

unsigned int money, xp, hp, challenges, skillleft, skillright,skylander_number;
bool pathleft, pathright;
Expand All @@ -110,8 +114,10 @@ int main(int argc, char* argv[])
case 'd': decrypt = true; break;
case 'P': portalOut = true; break;
case 'p': portalIn = true; break;
case 'K': RawRead = true; break;
case 'D': dump = true; break;
case 'F': flash = true; break;
case 'W': RawWrite = true; break;
case 'i':
inFile = new char[strlen(optarg)+1];
strcpy(inFile,optarg);
Expand Down Expand Up @@ -178,6 +184,7 @@ int main(int argc, char* argv[])
exit (0);
}


if (list) {
printf ("Listing Skylanders.\n\n");

Expand All @@ -188,13 +195,13 @@ int main(int argc, char* argv[])
}

// validate command line options
if ( (!inFile && !portalIn) || (inFile && portalIn)) {
if ( (!inFile && !portalIn && !RawRead) || (inFile && portalIn)) {
printf ("Must Choose One of: read from file -i <file> or read from portal -p\n");
usage();
exit(0);
}

if (!outFile && !portalOut && !dump) {
if (!outFile && !portalOut && !dump && !RawWrite) {
printf ("Nothing to write. Choose file -o, portal -P or dump -D\n");
usage();
exit(0);
Expand All @@ -220,6 +227,10 @@ int main(int argc, char* argv[])
if (portalIn) {
skio->initWithPortal(skylander_number);
}
if (RawRead) {
skio->initRawReadPortal(skylander_number);
}

if (inFile) {
if (decrypt) {
skio->initWithEncryptedFile(inFile);
Expand Down Expand Up @@ -279,13 +290,8 @@ int main(int argc, char* argv[])
if (autoFile) {
Skylander * sky;
sky = skio->getSkylander();
unsigned long num = sky->getSerial();
unsigned long serial = ((num>>24)&0xff) | // move byte 3 to byte 0
((num<<8)&0xff0000) | // move byte 1 to byte 2
((num>>8)&0xff00) | // move byte 2 to byte 1
((num<<24)&0xff000000); // byte 0 to byte 3

sprintf(outFile, "%s - %s - %08lX.dmp", sky->getToyTypeName(), sky->getPath(), serial);
sprintf(outFile, "%s.bin", sky->getToyTypeName());
printf("Saving to automatic filename: %s\n", outFile);
}

Expand All @@ -298,6 +304,9 @@ int main(int argc, char* argv[])
if (portalOut) {
skio->writeSkylanderToPortal(skylander_number);
}
if (RawWrite) {
skio->RawWriteSkylanderToPortal(skylander_number);
}

delete skio;

Expand Down
Loading