MEXP(int) cm_pe_fixed_version(cm_pe_t pe, cm_pe_res_t* res, cm_pe_version_t* ver) { cm_pe_section_t* sect = (pe->sections + 3); #if BIGENDIAN uint32_t check = 0xBD04EFFE; #else uint32_t check = 0xFEEF04BD; #endif uint32_t rva; uint32_t size; uint32_t offset; uint32_t align; if (!pe || !res || !ver) return 0; if (fseek(pe->f, res->file_offset, SEEK_SET) == -1) return 0; if (fread(&rva, 4, 1, pe->f) != 1) return 0; if (fread(&size, 4, 1, pe->f) != 1) return 0; #if BIGENDIAN rva = SWAP4(rva); size = SWAP4(size); #endif offset = sect->raw_data_offset + (rva - sect->virtual_address) + 0x26; align = 4 -(offset & 0xF % 4); if (align < 4) offset += align; if (fseek(pe->f, offset, SEEK_SET) == -1) return 0; if (fread(ver, sizeof(cm_pe_version_t), 1, pe->f) != 1) return 0; if (ver->dwSignature != check) return 0; #if BIGENDIAN ver->dwSignature = SWAP32(ver->dwSignature); ver->dwStrucVersion = SWAP32(ver->dwStrucVersion); ver->dwFileVersionMS = SWAP32(ver->dwFileVersionMS); ver->dwFileVersionLS = SWAP32(ver->dwFileVersionLS); ver->dwProductVersionMS = SWAP32(ver->dwProductVersionMS); ver->dwProductVersionLS = SWAP32(ver->dwProductVersionLS); ver->dwFileFlagsMask = SWAP32(ver->dwFileFlagsMask); ver->dwFileFlags = SWAP32(ver->dwFileFlags); ver->dwFileOS = SWAP32(ver->dwFileOS); ver->dwFileType = SWAP32(ver->dwFileType); ver->dwFileSubtype = SWAP32(ver->dwFileSubtype); ver->dwFileDateMS = SWAP32(ver->dwFileDateMS); ver->dwFileDateLS = SWAP32(ver->dwFileDateLS); #endif return 1; }
// -------------------------------------------------- Host WSAClientSocket::getLocalHost() { struct sockaddr_in localAddr; int len = sizeof(localAddr); if (getsockname(sockNum, (sockaddr *)&localAddr, &len) == 0) return Host(SWAP4(localAddr.sin_addr.s_addr),0); else return Host(0,0); }
/** * Writes a 32 bit integer to a StreamWrite. * * @param stream The StreamWrite to write to. * @param value The value to write. */ EXPORT void streamWriteUInt(StreamWrite* stream, uint32_t value) { if (!stream) { return; } if (stream->index + 4 >= stream->bufferLength) { streamWriteExpand(stream); } if (stream->endianness != ENDIANNESS_NATIVE) { value = SWAP4(value); } *(uint32_t*)(stream->data + stream->index) = value; streamWriteSkip(stream, 4); }
NMErr NetworkSendPlayerMessage ( const char *message, /* ptr to message string to send */ NMUInt32 messageType /* type of message (question, info, etc. */ ) { char buffer[256]; MessagePacketPtr theMessage = (MessagePacketPtr)buffer; clientPlayer *theClient; NMErr err = kNMNoError; strcpy(theMessage->str,message); theMessage->type = messageType; /* on little_endian systems (x86,etc) we need to swap our 4 byte type value into network(big-endian) format */ #if (little_endian) theMessage->type = SWAP4(theMessage->type); #endif /* As a host, to send a message to all players, we just go through our list of client endpoints and send to each of them */ theClient = _clientList; while (theClient != NULL) { /* If we've closed a client and are waiting for its close-complete, we don't send stuff to it*/ if (theClient->closed == false) { //printf("sending packat to %p\n",theClient->endpoint); err = ProtocolSendPacket( theClient->endpoint, /* which endpoint */ theMessage, /* data */ sizeof(*theMessage) + strlen(theMessage->str), /* data size */ 0); /* flags */ } theClient = theClient->next; } return err; }
NMErr NetworkSendAnswer ( char answer /* the answer to send (just a char!) */ ) { NMErr err = kNMNoError; MessagePacket_t theMessage; theMessage.type = kMessageType_Answer; theMessage.str[0] = answer; /* on little_endian systems (x86,etc) we need to swap our 4 byte type value into network(big-endian) format */ #if (little_endian) theMessage.type = SWAP4(theMessage.type); #endif /* To send messages to the host, we just use our local client endpoint */ err = ProtocolSendPacket( _ourClientEndpoint, /* which endpoint */ &theMessage, /* data */ sizeof(theMessage), /* data size */ 0); /* flags */ return err; }
NMErr NetworkSendName ( char *name /* the name to send */ ) { char buffer[256]; MessagePacketPtr theMessage = (MessagePacketPtr)buffer; NMErr err = kNMNoError; strcpy(theMessage->str,name); theMessage->type = kMessageType_Name; /* on little_endian systems (x86,etc) we need to swap our 4 byte type value into network(big-endian) format */ #if (little_endian) theMessage->type = SWAP4(theMessage->type); #endif err = ProtocolSendPacket( _ourClientEndpoint, /* which endpoint */ theMessage, /* data */ sizeof(*theMessage) + strlen(theMessage->str), /* data size */ 0); /* flags */ return err; }
MEXP(cm_pe_resdir_t*) cm_pe_load_resources(cm_pe_t pe) { cm_pe_section_t* sect; cm_pe_resdir_t* root = (cm_pe_resdir_t*) 0; cm_pe_resdir_t* dir; cm_pe_resdir_t* subdirs; cm_pe_res_t res; cm_pe_res_t* resources; cm_stack_t stack; size_t i; uint32_t base; // no need to check validity of pe pointer; cm_pe_get_section does this sect = cm_pe_get_section(pe, ".rsrc"); if (!sect) return (cm_pe_resdir_t*) 0; root = (cm_pe_resdir_t*) malloc(sizeof(cm_pe_resdir_t)); if (!root) return (cm_pe_resdir_t*) 0; base = sect->raw_data_offset; if (!cm_pe_load_resdir(pe->f, base, root)) { free(root); return (cm_pe_resdir_t*) 0; } stack = cm_stack_create(); if (!stack) { free(root); return (cm_pe_resdir_t*) 0; } cm_stack_push(stack, root); while ( (dir = (cm_pe_resdir_t*) cm_stack_pop(stack)) ) { while (dir->subdir_count + dir->resource_count < dir->named_entry_count + dir->id_entry_count) { if (fseek(pe->f, dir->offset, SEEK_SET) == -1) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } if (fread(&res, CM_RES_REAL_SIZE, 1, pe->f) != 1) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } #if BIGENDIAN res.name = SWAP4(res.name); res.offset = SWAP4(res.offset); #endif if (res.offset & 0x80000000) { // subdirectory i = dir->subdir_count++; subdirs = (cm_pe_resdir_t*) realloc(dir->subdirs, sizeof(cm_pe_resdir_t) * dir->subdir_count); if (!subdirs) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } dir->subdirs = subdirs; cm_stack_push(stack, dir); dir->offset += CM_RES_REAL_SIZE; dir = (subdirs + i); res.offset &= 0x7FFFFFFF; res.file_offset = base + res.offset; if (!cm_pe_load_resdir(pe->f, res.file_offset, dir)) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } dir->name = res.name; cm_stack_push(stack, dir); break; } // real resource res.file_offset = base + res.offset; i = dir->resource_count++; resources = (cm_pe_res_t*) realloc(dir->resources, sizeof(cm_pe_res_t) * dir->resource_count); if (!resources) { cm_pe_unload_resources(root); cm_stack_destroy(stack); return (cm_pe_resdir_t*) 0; } dir->resources = resources; memcpy(dir->resources + i, &res, sizeof(cm_pe_res_t)); dir->offset += CM_RES_REAL_SIZE; } } cm_stack_destroy(stack); return root; }
uint32_t SRPCalcU(const unsigned char *B) { unsigned char hash[20]; SHA1(B, 32, hash); return SWAP4(*(uint32_t *)hash); }
static void _callBack( PEndpointRef inEndpoint, void* inContext,NMCallbackCode inCode, NMErr inError,void* inCookie ) { /*we have to respond to connect requests immediately, because when we connect to ourself, we'll be in a ProtocolOpenEndpoint() call and won't be able to call our message checking function*/ if (inCode == kNMConnectRequest) { /*this is a tiny bit sloppy to be comparing values at interrupt time - we should use some sort of mutual-exclusion setup so we can't have two threads manipulating these values simultaneously. Anyway, for our simple purposes this is fine*/ if (_playerCount < _maxPlayers) { clientPlayer *thePlayer; /*create a player struct and pass it as our context for this new endpoint we dont', however, add it to our list yet - we gotta wait for our accept complete (we shouldnt at interrupt time anyway)*/ thePlayer = (clientPlayer*)_interruptSafeAllocate(sizeof(*thePlayer)); strcpy(thePlayer->name,"mr. untitled"); /*until we get a name message from the guy, we hereby dub him mr. untitled*/ ProtocolAcceptConnection(inEndpoint,inCookie,_callBack,thePlayer); _playerCount++; } else /* Rejected!!! */ ProtocolRejectConnection(inEndpoint,inCookie); } else { MessageStorageNode *theStorageNode; /*theres one or more datagrams waiting*/ if (inCode == kNMDatagramData){ NMUInt32 dataLength = kMaxMessageSize; NMFlags flags = 0; char buffer[kMaxMessageSize]; NMErr err; /* receive packets until there are no more to be found */ err = ProtocolReceivePacket(inEndpoint,(void*)buffer,&dataLength,&flags); while (!err) { /* we got a packet - make a node big enough to hold it, save all the message info, and copy the data we received (in this case just a string) to it */ theStorageNode = _newMessageStorageNode(dataLength); theStorageNode->endpoint = inEndpoint; theStorageNode->context = inContext; theStorageNode->cookie = inCookie; theStorageNode->code = inCode; theStorageNode->type = ((MessagePacketPtr)buffer)->type; /* we just pulled a 4 byte integer off the network - if we're on a little-endian system (x86,etc) we need to swap it out of big-endian format */ #if (little_endian) theStorageNode->type = SWAP4(theStorageNode->type); #endif strcpy(theStorageNode->str,((MessagePacketPtr)buffer)->str); /*add it to our interrupt-safe list and try for the next one*/ _messageList.Enqueue(&theStorageNode->fNext); err = ProtocolReceivePacket(inEndpoint,buffer,&dataLength,&flags); } } /*its some other message - make a storage node without any extra space for data and copy the info in */ else { theStorageNode = _newMessageStorageNode(0); theStorageNode->endpoint = inEndpoint; theStorageNode->context = inContext; theStorageNode->cookie = inCookie; theStorageNode->code = inCode; /*add it to our interrupt-safe list*/ _messageList.Enqueue(&theStorageNode->fNext); } } }
MEXP(int) cm_pe_fixed_version(cm_pe_t pe, cm_pe_res_t* res, cm_pe_version_t* ver) { // find ".rsrc" section cm_pe_section_t* sect = pe->sections; { int i=0; for(; i<pe->header.section_count; ++i) { if(strncmp(sect[i].name,".rsrc",sizeof(sect[i].name))==0) { sect = §[i]; break; } } if(i == pe->header.section_count) // no resources ??? return 0; } #if BIGENDIAN uint32_t check = 0xBD04EFFE; #else uint32_t check = 0xFEEF04BD; #endif uint32_t rva; uint32_t size; uint32_t offset; if (!pe || !res || !ver) return 0; if (fseek(pe->f, res->file_offset, SEEK_SET) == -1) return 0; if (fread(&rva, 4, 1, pe->f) != 1) return 0; if (fread(&size, 4, 1, pe->f) != 1) return 0; #if BIGENDIAN rva = SWAP4(rva); size = SWAP4(size); #endif offset = sect->raw_data_offset + (rva - sect->virtual_address) + 0x26; offset = (offset+3) & 0xFFFFFFFC; // align 4 byte if (fseek(pe->f, offset, SEEK_SET) == -1) return 0; if (fread(ver, sizeof(cm_pe_version_t), 1, pe->f) != 1) return 0; if (ver->dwSignature != check) return 0; #if BIGENDIAN ver->dwSignature = SWAP32(ver->dwSignature); ver->dwStrucVersion = SWAP32(ver->dwStrucVersion); ver->dwFileVersionMS = SWAP32(ver->dwFileVersionMS); ver->dwFileVersionLS = SWAP32(ver->dwFileVersionLS); ver->dwProductVersionMS = SWAP32(ver->dwProductVersionMS); ver->dwProductVersionLS = SWAP32(ver->dwProductVersionLS); ver->dwFileFlagsMask = SWAP32(ver->dwFileFlagsMask); ver->dwFileFlags = SWAP32(ver->dwFileFlags); ver->dwFileOS = SWAP32(ver->dwFileOS); ver->dwFileType = SWAP32(ver->dwFileType); ver->dwFileSubtype = SWAP32(ver->dwFileSubtype); ver->dwFileDateMS = SWAP32(ver->dwFileDateMS); ver->dwFileDateLS = SWAP32(ver->dwFileDateLS); #endif return 1; }