vswprintf : Mac %s vs Windows %S - stdstring

I'm using vswprintf to form a wchar_t* str from a formatted string. In that formatted string, to print a std:string, Mac accepts as %s while Windows VS2008 accepts as %S. Example
void widePrint(const wchar_t* fmt, ...) {
va_list args;
va_start(args, fmt);
wchar_t buf[32*1024] = {0};
vswprintf(buf,(32*1024 - 1),fmt, args);
...//Prints buf
...
}
...
std::string str = "normal String";
std::wstring strW = L"wideStr";
widePrint(L"str: %S wStr: %ls",str.c_str(), strW.c_str()); //Windows - VS2008
widePrint(L"str: %s wStr: %ls",str.c_str(), strW.c_str()); //Mac - XCode 3.2.6
Why is this difference in behavior? Is there any way to print std::string/char* in vswprintf in platform independent form?

%hs is the platform independent way of printing char[] in both Win and Mac

Related

How to create a snort content rule

I am new into using snort and I don't know how to properly create rules.
I want someone to explain me how to create a rule for detection of a specific content. For example: I want to generate an alert when I search on Google the word 'terrorism'.
I tried to create the rule with what I've seen on Youtube or Google, as examples, but none of them works and I don't know what to try anymore. For instance, I am using Snort 2.9.9
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"terrorism content found"; content:"terrorism"; nocase; sid:1000000;)
I don't have any errors from the local.rules file, but I got the line 'include $RULE_PATH/snort.rules' commented because of some problems with PulledPork.
I expect to have an alert in the CLI, but there is no output.
I know that this is already too late but here's the answer for future reference.
The packets are probably being sent using HTTPS connection (which is why they are encrypted).
This might be a reason why there are no alerts.
Please refer here for a detailed explanation.
rules are ready, u just replace, alert with sdrop:
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
and you can use include in config file
O.K
Answer is here: http://manpages.ubuntu.com/manpages/xenial/man8/u2spewfoo.8.html
Download Snort source, Make logs costume, write ur code to get log stream in control
Then Build source and run
Be successful :)
It is possible to send alert messages and some packet relevant data
from snort through a unix socket, to perform additional separate
processing of alert data.
Snort has to be built with spo_unsock.c/h output plugin is built in and
-A unsock (or its equivalent through the config file) is
used. The unix socket file should be created in /dev/snort_alert. Your
‘client’ code should act as ‘server’ listening to this unix socket.
Snort will be sending you Alertpkt structures which contain alert
message, event id. Original datagram, libpcap pkthdr, and offsets to
datalink, netlayer, and transport layer headers.
Below is an example how unix sockets could be used. If you have any
comments bug reports, and feature requests, please contact
snort-devel#lists.sourceforge.net or drop me an email to fygrave at
tigerteam dot net.
-Fyodor
[for copyright notice, see snort distribution code]
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include
#include "snort.h"
int sockfd;
void
sig_term (int sig)
{
printf (“Exiting!\n”);
close (sockfd);
unlink (UNSOCK_FILE);
exit (1);
}
int
main (void)
{
struct sockaddr_un snortaddr;
struct sockaddr_un bogus;
Alertpkt alert;
Packet *p;
int recv;
socklen_t len = sizeof (struct sockaddr_un);
if ((sockfd = socket (AF_UNIX, SOCK_DGRAM, 0)) < 0)
{
perror (“socket”);
exit (1);
}
bzero (&snortaddr, sizeof (snortaddr));
snortaddr.sun_family = AF_UNIX;
strcpy (snortaddr.sun_path, UNSOCK_FILE);
if (bind (sockfd, (struct sockaddr *) &snortaddr, sizeof (snortaddr)) < 0)
{
perror (“bind”);
exit (1);
}
signal(SIGINT, sig_term);
while ((recv = recvfrom (sockfd, (void *) &alert, sizeof (alert),
0, (struct sockaddr *) &bogus, &len)) > 0)
{
/* do validation of recv if you care */
if (!(alert.val & NOPACKET_STRUCT))
{
if ((p = calloc (1, sizeof (Packet))) == NULL)
{
perror ("calloc");
exit (1);
}
p->pkt = alert.pkt;
p->pkth = &alert.pkth;
if (alert.dlthdr)
p->eh = (EtherHdr *) (alert.pkt + alert.dlthdr);
if (alert.nethdr)
{
p->iph = (IPHdr *) (alert.pkt + alert.nethdr);
if (alert.transhdr)
{
switch (p->iph->ip_proto)
{
case IPPROTO_TCP:
p->tcph = (TCPHdr *) (alert.pkt + alert.transhdr);
break;
case IPPROTO_UDP:
p->udph = (UDPHdr *) (alert.pkt + alert.transhdr);
break;
case IPPROTO_ICMP:
p->icmph = (ICMPHdr *) (alert.pkt + alert.transhdr);
break;
default:
printf ("My, that's interesting.\n");
} /* case */
} /* thanshdr */
} /* nethdr */
if (alert.data)
p->data = alert.pkt + alert.data;
/* now do whatever you want with these packet structures */
} /* if (!NOPACKET_STRUCT) */
printf ("%s [%d]\n", alert.alertmsg, alert.event.event_id);
if (!(alert.val & NOPACKET_STRUCT))
if (p->iph && (p->tcph || p->udph || p->icmph))
{
switch (p->iph->ip_proto)
{
case IPPROTO_TCP:
printf ("TCP from: %s:%d ",
inet_ntoa (p->iph->ip_src),
ntohs (p->tcph->th_sport));
printf ("to: %s:%d\n", inet_ntoa (p->iph->ip_dst),
ntohs (p->tcph->th_dport));
break;
case IPPROTO_UDP:
printf ("UDP from: %s:%d ",
inet_ntoa (p->iph->ip_src),
ntohs (p->udph->uh_sport));
printf ("to: %s:%d\n", inet_ntoa (p->iph->ip_dst),
ntohs (p->udph->uh_dport));
break;
case IPPROTO_ICMP:
printf ("ICMP type: %d code: %d from: %s ",
p->icmph->type,
p->icmph->code, inet_ntoa (p->iph->ip_src));
printf ("to: %s\n", inet_ntoa (p->iph->ip_dst));
break;
}
}
}
perror (“recvfrom”);
close (sockfd);
unlink (UNSOCK_FILE);
return 0;
}

Problem executing code (C/Mongo C driver) on different installation than where first compiled

I have a program compiled and running on Ubuntu server 16.04, in C using Mongo C driver. This works without a problem. If I move this executable to a new installation, I get an error when executing;
testuser#usrv1604:~/bin$ ./error-example
./error-example: symbol lookup error: ./error-example: undefined symbol: mongoc_uri_new_with_error
Always the same error message.
Please see simplified code example below:
#include <stdio.h>
#include <strings.h>
#include <mongoc.h>
int
main (int argc, char *argv[])
{
const char *uri_string = "mongodb://localhost:27017";
mongoc_uri_t *uri;
mongoc_client_t *client;
mongoc_database_t *database;
mongoc_collection_t *collection;
bson_t *command, reply, *insert;
bson_t *b;
bson_error_t error;
mongoc_init ();
uri = mongoc_uri_new_with_error (uri_string, &error);
if (!uri) {
fprintf (stderr,
"failed to parse URI: %s\n"
"error message: %s\n",
uri_string,
error.message);
return EXIT_FAILURE;
}
client = mongoc_client_new_from_uri (uri);
if (!client) {
fprintf(stderr, "mongoc_client_new_from_uri() failed \n");
return EXIT_FAILURE;
}
mongoc_client_set_appname (client, "log-lme");
database = mongoc_client_get_database (client, "sds");
collection = mongoc_client_get_collection (client, "sds", "test");
//
// update db
//
// clean up
mongoc_collection_destroy (collection);
mongoc_database_destroy (database);
mongoc_uri_destroy (uri);
mongoc_client_destroy (client);
mongoc_cleanup ();
return EXIT_SUCCESS;
}
Please check the mongoc driver version installed on the target system. You must have version 1.8 or later to use this API: http://mongoc.org/libmongoc/1.8.0/mongoc_uri_new_with_error.html

How to use and compile standard c Lib in vala?

I'm just start few test in vala.
Vala is new for me . Sure I started to read a lot of tuto, but I don't understand my mistake.
how to use and compile the follow code?
using Gtk;
#include <stdio.h>
// compile with valac --pkg gtk+-3.0 hello_world_gtk_01.vala
public const int EXIT_SUCCESS=0;
int main (string[] args)
{
Gtk.init (ref args);
var window = new Window ();
window.title = "Hello, World!";
window.border_width = 10;
window.window_position = WindowPosition.CENTER;
window.set_default_size (350, 70);
window.destroy.connect (Gtk.main_quit);
stdout.printf ("Version de gtk: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION);
stdout.printf ("Version de gtk: %u.%u.%u\n", get_major_version() , get_minor_version(), get_micro_version());
string name, str;
name = "Version de gtk: ";
sprintf(str, "%d", get_major_version());
name = name+ str;
sprintf(str, "%d", get_minor_version());
name = name+ str;
sprintf(str, "%d", get_micro_version());
name = name+ str+ "\n";
var label = new Label (name);
window.add (label);
window.show_all ();
Gtk.main ();
return EXIT_SUCCESS;
}
What is bad ?
Gcc said
hello_world_gtk_01.vala:2.2-2.9: error: syntax error, invalid preprocessing directive
#include <stdio.h>
^^^^^^^^
hello_world_gtk_01.vala:2.10-2.10: error: syntax error, expected identifier
#include <stdio.h>
^
Compilation failed: 2 error(s), 0 warning(s)
could you help me to understand how to manage stdio?
Vala generates C code, but you can't pass C straight from the Vala file to the generated C. The Vala [CCode] attribute gives fine control over the generated C, but you won't need that in most cases. For an example of standard C names and their GLib equivalents take a look at the glib-2.0.vapi file in the Vala repository. Other standard C and POSIX extensions are in posix.vapi. There is also an in depth tutorial on writing a binding from Vala to a C library. Writing a binding, however, is a more advanced topic and what you are trying to achieve in your example doesn't need a new binding.
Your example uses string interpolation. In Vala a data type can have a method, so one way to write what you want would be:
name = "Version de gtk: %u.%u.%u\n".printf( get_major_version (), get_minor_version (), get_micro_version ());
Vala also has a string template syntax, #"", and and then an expression, $(), inside the string is evaluated. For example:
name = #"Version de gtk: $(get_major_version ()).$(get_minor_version ()).$(get_micro_version ())\n";
This works because uint, the return value of the function calls, has a to_string () method that is implicitly called by the string template.
Here's your example modified to use the string template method:
using Gtk;
// compile with valac --pkg gtk+-3.0 hello_world_gtk_01.vala
public const int EXIT_SUCCESS=0;
int main (string[] args)
{
Gtk.init (ref args);
var window = new Window ();
window.title = "Hello, World!";
window.border_width = 10;
window.window_position = WindowPosition.CENTER;
window.set_default_size (350, 70);
window.destroy.connect (Gtk.main_quit);
stdout.printf ("Version de gtk: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION);
stdout.printf ("Version de gtk: %u.%u.%u\n", get_major_version() , get_minor_version(), get_micro_version());
var name = #"Version de gtk: $(get_major_version ()).$(get_minor_version ()).$(get_micro_version ())\n";
var label = new Label (name);
window.add (label);
window.show_all ();
Gtk.main ();
return EXIT_SUCCESS;
}

Most UEFI protocols are reported as "unsupported"

I'm writing an EFI executable on a SoC device (Up Board) to help us automate BIOS updates and PXE boots for installating our software on numerous devices.
The problem I have is that seemingly most of the protocols in the specification are "unsupported" on this platform, even basic file system tasks. The only one I've successfully used is the LOADED_IMAGE_PROTOCOL. I'm using gnu-efi to compile the code, basing my code to this example https://mjg59.dreamwidth.org/18773.html. Is there something I'm doing wrong, or is this simply the firmware absolutely not implementing any of the protocols?
The American Megatrends utility "AfuEfix64.efi" is capable of retrieving BIOS information, and the SoC BIOS updates are done using an Intel's EFI executable. Both are closed source, unfortunately. My initial idea would have been to write a script that parses the output from these executables, but I don't think the EFI shell has much features for this type of tasks, so I moved on to writing an EFI executable to perform this.
Minimal code showing this:
#include <efi.h>
#include <efilib.h>
#include <x86_64/efibind.h>
// gnu-efi does not currently define firmware management
// https://raw.githubusercontent.com/tianocore/edk2/master/MdePkg/Include/Protocol/FirmwareManagement.h
#include "efifirmware.h"
// gnu-efi does not currently define this
#define EFI_LOAD_FILE2_PROTOCOL_GUID \
{ 0x4006c0c1, 0xfcb3, 0x403e, \
{ 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d }}
typedef EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE2_PROTOCOL;
void tryProtocol(EFI_GUID proto_guid, void** out, const CHAR16* name,
EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemTable) {
EFI_STATUS status;
status = uefi_call_wrapper(systemTable->BootServices->HandleProtocol, 3,
imageHandle, &proto_guid, out);
if (EFI_ERROR(status)) {
Print(L"HandleProtocol error for %s: %r\n", name, status);
} else {
Print(L"Protocol %s is supported\n", name);
}
}
void tryProtocols(EFI_HANDLE imgh, EFI_SYSTEM_TABLE* syst) {
EFI_LOADED_IMAGE* loaded_image = NULL;
EFI_GUID guid_imgprot = LOADED_IMAGE_PROTOCOL;
tryProtocol(guid_imgprot, (void**)&loaded_image,
L"LOADED_IMAGE_PROTOCOL", imgh, syst);
Print(L"Image base: %lx\n", loaded_image->ImageBase);
Print(L"Image size: %lx\n", loaded_image->ImageSize);
Print(L"Image file: %s\n", DevicePathToStr(loaded_image->FilePath));
EFI_FIRMWARE_MANAGEMENT_PROTOCOL* fw_manage = NULL;
EFI_GUID guid_fwman_prot = EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID;
tryProtocol(guid_fwman_prot, (void**)&fw_manage,
L"FIRMWARE_MANAGEMENT_PROTOCOL", imgh, syst);
EFI_LOAD_FILE_PROTOCOL* load_file = NULL;
EFI_GUID guid_loadf_prot = EFI_LOAD_FILE_PROTOCOL_GUID;
tryProtocol(guid_loadf_prot, (void**)&load_file,
L"LOAD_FILE_PROTOCOL", imgh, syst);
EFI_LOAD_FILE2_PROTOCOL* load_file2 = NULL;
EFI_GUID guid_loadf2_prot = EFI_LOAD_FILE2_PROTOCOL_GUID;
tryProtocol(guid_loadf2_prot, (void**)&load_file2,
L"LOAD_FILE2_PROTOCOL", imgh, syst);
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* simple_fs = NULL;
EFI_GUID guid_simple_fs_prot = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
tryProtocol(guid_simple_fs_prot, (void**)&simple_fs,
L"SIMPLE_FILE_SYSTEM_PROTOCOL", imgh, syst);
EFI_DISK_IO_PROTOCOL* disk = NULL;
EFI_GUID guid_disk_io_prot = EFI_DISK_IO_PROTOCOL_GUID;
tryProtocol(guid_disk_io_prot, (void**)&disk,
L"DISK_IO_PROTOCOL", imgh, syst);
EFI_BLOCK_IO_PROTOCOL* block = NULL;
EFI_GUID guid_block_io_prot = EFI_BLOCK_IO_PROTOCOL_GUID;
tryProtocol(guid_block_io_prot, (void**)&block,
L"BLOCK_IO_PROTOCOL", imgh, syst);
}
EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemTable) {
InitializeLib(imageHandle, systemTable);
Print(L"Image loaded\n");
tryProtocols(imageHandle, systemTable);
return EFI_SUCCESS;
}
Here's the output for running it:
EFI Shell version 2.40 [5.11]
Current running mode 1.1.2
Device mapping table
fs0 :HardDisk - Alias hd6b blk0
PciRoot(0x0)/Pci(0x10,0x0)/Ctrl(0x0)/HD(1,GPT,2DCDDADD-8F3A-4A77-94A9-010A8C700BB8,0x800,0x100000)
fs1 :Removable HardDisk - Alias hd9g0a0b blk1
PciRoot(0x0)/Pci(0x14,0x0)/USB(0x6,0x0)/USB(0x0,0x0)/HD(1,MBR,0x528E6A1F,0x800,0x1CDE800)
blk0 :HardDisk - Alias hd6b fs0
PciRoot(0x0)/Pci(0x10,0x0)/Ctrl(0x0)/HD(1,GPT,2DCDDADD-8F3A-4A77-94A9-010A8C700BB8,0x800,0x100000)
blk1 :Removable HardDisk - Alias hd9g0a0b fs1
PciRoot(0x0)/Pci(0x14,0x0)/USB(0x6,0x0)/USB(0x0,0x0)/HD(1,MBR,0x528E6A1F,0x800,0x1CDE800)
blk2 :HardDisk - Alias (null)
PciRoot(0x0)/Pci(0x10,0x0)/Ctrl(0x0)/HD(2,GPT,8AC0F94E-3CA2-4C03-BE00-3A69721CC391,0x100800,0x1C1F7DF)
blk3 :BlockDevice - Alias (null)
PciRoot(0x0)/Pci(0x10,0x0)/Ctrl(0x0)
blk4 :BlockDevice - Alias (null)
PciRoot(0x0)/Pci(0x10,0x0)/Ctrl(0x1)
blk5 :BlockDevice - Alias (null)
PciRoot(0x0)/Pci(0x10,0x0)/Ctrl(0x2)
blk6 :Removable BlockDevice - Alias (null)
PciRoot(0x0)/Pci(0x14,0x0)/USB(0x6,0x0)/USB(0x0,0x0)
Press ESC in 4 seconds to skip startup.nsh, any other key to continue.
fs1:\> tryprotocols.efi
Image loaded
Protocol LOADED_IMAGE_PROTOCOL is supported
Image base: 55BA6000
Image size: F000
Image file: \/tryprotocols.efi
HandleProtocol error for FIRMWARE_MANAGEMENT_PROTOCOL: Unsupported
HandleProtocol error for LOAD_FILE_PROTOCOL: Unsupported
HandleProtocol error for LOAD_FILE2_PROTOCOL: Unsupported
HandleProtocol error for SIMPLE_FILE_SYSTEM_PROTOCOL: Unsupported
HandleProtocol error for DISK_IO_PROTOCOL: Unsupported
HandleProtocol error for BLOCK_IO_PROTOCOL: Unsupported
fs1:\>
And here's the Makefile I use to compile it:
ARCH=x86_64
OBJS=tryprotocols.o
TARGET=tryprotocols.efi
TARGET_SO=$(TARGET:.efi=.so)
GNUEFIDIR=/home/gekko/gnu-efi-3.0.8
EFIINC=$(GNUEFIDIR)/inc
EFIINCS=-I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol
LIB=$(GNUEFIDIR)/$(ARCH)/lib
EFILIB=$(GNUEFIDIR)/gnuefi
EFI_CRT_OBJS=$(GNUEFIDIR)/$(ARCH)/gnuefi/crt0-efi-$(ARCH).o
EFI_LDS=$(EFILIB)/elf_$(ARCH)_efi.lds
CFLAGS=$(EFIINCS) -fno-stack-protector -fpic \
-fshort-wchar -mno-red-zone -Wall
ifeq ($(ARCH),x86_64)
CFLAGS += -DEFI_FUNCTION_WRAPPER
endif
LDFLAGS=-nostdlib -znocombreloc -T $(EFI_LDS) -shared \
-Bsymbolic -L $(EFILIB) -L $(LIB) $(EFI_CRT_OBJS)
all: $(TARGET)
$(TARGET_SO): $(OBJS)
ld $(LDFLAGS) $(OBJS) -o $# -lefi -lgnuefi
%.efi: %.so
objcopy -j .text -j .sdata -j .data -j .dynamic \
-j .dynsym -j .rel -j .rela -j .reloc \
--target=efi-app-$(ARCH) $^ $#
clean:
rm -f *.o
rm -f $(TARGET)
rm -f $(TARGET_SO)
EDIT: Modified version that properly uses LocateProtocol() to find the protocols, and uses them to open and close a file.
#include <efi.h>
#include <efilib.h>
#include <x86_64/efibind.h>
BOOLEAN tryProtocol(EFI_GUID proto_guid, void** out, const CHAR16* name,
EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemTable) {
*out = NULL;
EFI_STATUS status;
EFI_HANDLE interface = NULL;
status = uefi_call_wrapper(systemTable->BootServices->LocateProtocol, 3,
&proto_guid, NULL, &interface);
if (EFI_ERROR(status)) {
Print(L"LocateProtocol error for %s: %r\n", name, status);
return FALSE;
}
Print(L"Locate protocol address: %s, %x\n", name, interface);
*out = interface;
return TRUE;
}
EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE* systemTable) {
InitializeLib(imageHandle, systemTable);
Print(L"Image loaded\n");
EFI_LOADED_IMAGE* loaded_image = NULL;
EFI_GUID guid_imgprot = LOADED_IMAGE_PROTOCOL;
if (tryProtocol(guid_imgprot, (void**)&loaded_image,
L"LOADED_IMAGE_PROTOCOL", imageHandle, systemTable) != TRUE) {
Print(L"Missing required protocol. Aborting\n");
return EFI_SUCCESS;
}
Print(L"Image base: %lx\n", loaded_image->ImageBase);
Print(L"Image size: %lx\n", loaded_image->ImageSize);
Print(L"Image file: %s\n", DevicePathToStr(loaded_image->FilePath));
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* simple_fs = NULL;
EFI_GUID guid_simple_fs_prot = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
if (tryProtocol(guid_simple_fs_prot, (void**)&simple_fs,
L"EFI_SIMPLE_FILE_SYSTEM_PROTOCOL", imageHandle, systemTable) != TRUE) {
Print(L"Missing required protocol. Aborting\n");
return EFI_SUCCESS;
}
EFI_FILE_PROTOCOL* vol_proto = NULL;
EFI_STATUS status;
Print(L"dereffing\n");
Print(L"address of OpenVolume: %x\n", simple_fs->OpenVolume);
status = uefi_call_wrapper(simple_fs->OpenVolume, 2, simple_fs, &vol_proto);
if (EFI_ERROR(status)) {
Print(L"Error opening volume: %r\n", status);
return EFI_SUCCESS;
}
Print(L"SIMPLE_FILE_SYSTEM volume opened\n");
EFI_FILE_PROTOCOL* f;
CHAR16 fname[10] = L"foo.txt\0";
UINT64 openmode = EFI_FILE_MODE_READ;
UINT64 attr = 0;
status = uefi_call_wrapper(vol_proto->Open, 5, vol_proto, &f, fname, openmode, attr);
if (EFI_ERROR(status)) {
Print(L"Error opening file: %r\n", status);
return EFI_SUCCESS;
}
Print(L"opened file %s\n", fname);
// Spec says can only return EFI_SUCCESS
status = uefi_call_wrapper(vol_proto->Close, 1, f);
Print(L"Closed file\n");
return EFI_SUCCESS;
}
Where and how to access a specific protocol is not statically defined by the UEFI specification, but something that needs to be discovered at runtime. While a bit arduous, it makes it possible to write applications/drivers portable across vastly different UEFI implementations that all conform to the specification.
So you need to LocateProtocol() on each protocol you are intending to use before you can make use of HandleProtocol().
You get away with LOADED_IMAGE_PROTOCOL because that one is initialized with your ImageHandle referring to the instance of the currently executing image (your program).
This is covered in Matthew's post under the section That covers how to use protocols attached to the image handle. How about protocols that are attached to other handles?.

How to use expat-parser with Russian charsets?

I tried to use expat for XML parsing, and I have Russian symbols in XML file, this symbols incorrectly interpret by expat.
I got expired_str: Русский текст
Instead of: Русский текст
Here is my cutted code:
static int xmlParseStartup(char *buffer, int n, START_UP_T *startUp_sp)
{
void *buff;
XML_Parser parser_p = XML_ParserCreate("UTF-8");
if (!parser_p)
{
DEBUG("Unable to create parser!\n");
return RES_ERR;
}
XML_SetUserData(parser_p, (void *)startUp_sp);
XML_SetElementHandler(parser_p, startElement, endElement);
buff = XML_GetBuffer(parser_p, n);
memcpy(buff, buffer, n);
if (XML_STATUS_ERROR == XML_ParseBuffer(parser_p, n, TRUE))
{
DEBUG("%s at line %" XML_FMT_INT_MOD "u\n",
XML_ErrorString(XML_GetErrorCode(parser_p)),
XML_GetCurrentLineNumber(parser_p));
return RES_ERR;
}
return RES_OK;
}
static void XMLCALL startElement(void *userData,
const char *name,
const char **atts)
{
int i;
START_UP_T *startUp_sp = (START_UP_T *)userData;
for (i = 0; i < startUp_sp->depthPtr; i++)
{
fprintf(stderr, ".");
}
DEBUG("[%d]name: %s\n", startUp_sp->depthPtr, name);
if (0 == strcmp(name, "response"))
{
if (0 == strcmp(atts[i], "result"))
{
startUp_sp->result = atoi(atts[3]);
DEBUG("RESULT: %d\n", startUp_sp->result);
}
else if (0 == strcmp(atts[i], "status_str"))
{
strcpy(startUp_sp->expired_str, atts[3]);
DEBUG("EXPIRED_STR: %s\n", startUp_sp->expired_str);
}
else if (0 == strcmp(atts[i], "status_width"))
{
startUp_sp->status_width = atoi(atts[3]);
}
}
startUp_sp->depthPtr += 1;
}
static void XMLCALL endElement(void *userData,
const char *name)
{
START_UP_T *startUp_sp = (START_UP_T *)userData;
startUp_sp->depthPtr -= 1;
}
XML file:
<?xml version="1.0" encoding="UTF-8"?>
<startup>
<response name="result" value="0"/>
<response name="status_str" value="Русский текст"/>
<response name="status_width" value="120"/>
</startup>
You get a cp1251 representation of the UTF-8 char*-typed string, so the expat actually works fine - it is the console output you're having problems with.
If it is not the case, check for the utf8 marker at the beginning of the xml file (239, 187, 191 bytes in ASCII codes, or "п>ї" without quotes in CP-1251).
One more: You should check the actual encoding of the .xml file, looks like it is not what you think it is (utf-8). What editor do you use to create the file ?
The CP1251 representation of UTF-8 "Русский текст" string is "Р С_С_С_РєРёР№ С'РчРєС_С'".