Simple Reverse Engineering - Windows Mobile Development and Hacking General

I'm currently doing a little reverse engineering of Coredll so that I can understand how a few functions work. Occasionally I run across a function call to an address similar to F000BDD8. Is this a function call into the kernel or does it correspond to an address in the dll? If someone could point me to the correct reference, I'd appreciate it.
This is how it is layed out:
LDR r0, &0000b650
MOV lr, pc
MOV pc, r0
And at address 0000b650 the value is F000BDD8.
Thanks!

it is something like a "syscall" command on WinCE. The "FIRST_METHOD" value (0xF0010000) is subtracted form the given address, then value is divided by 2 (in your case we get -8468 or 0xff..ffdeec). If the value is negative it is "API call to an implicit handle. In this case, bits 30-16 of the method index indicate which entry in the system handle table." (probably its a typo in comment, bits 8-22 are used instead of 30-16). Lower bits are offset in SystemAPISets[] table for the function address.
For more information look into PrefetchAbort function in "PRIVATE\WINCEOS\COREOS\NK\KERNEL\ARM\armtrap.s" file, and ObjectCall function in "PRIVATE\WINCEOS\COREOS\NK\KERNEL\objdisp.c"
You should get PlatformBuilder and look into Wince 4.20 partial source code that is coming with it. It does not have much information on indexes inside SystemAPISets table for any table except for SystemAPISets[SH_WIN32] (SH_WIN32 == 0).

see this page for a list of systemcalls.
and this page for a description of how systemcalls work.
to convert a trap address ( like 0xF000BDD8 ) back to the syscall nrs:
Code:
$a= (0xf0010000-$addr)/4; # = 0x108a
$api=$a>>8; # 0x10 = SH_GDI
$call=$a&0xff; # 0x8a = ExtCreateRegion
( call defined in public/common/oak/inc/mwingdi.h )
hmm. not sure which is correct though, my wince-systemcalls page lists a different call signature than the headerfile. they should match.

Thank you for the information. I actually have the sample source that comes with the Platform Builder demo. In this case, the call I was investigating was the GetSysColorBrush API.
That brings me to another point. In several of the APIs a check is made to a value (KData->lpvTls[-20], I believe) to see if the 0-bit is 1. The only thing I can determine is whether or not this is checking for the ready state of the API. Whatever the case, it seems that this bit determines whether the function I mentioned earlier is called or whether a function address is loaded from RAM. It's really weird.
The main reason I'm doing this is so that I can access the system's brush cache for the system colors. I've noticed that if I intercept calls to GetSysColor and GetSysColorBrush, it only works for applications that have not called them yet. So, if I override the color for COLOR_BTNFACE, menubars for newly launched applications are colored correctly, but buttons (which belong to GWES) do not use the appropriate color. It's weird because my code has been injected into GWES.Exe.
I guess that brings me to my ultimate question of whether or not someone can point me to the location in RAM where the system brush cache is stored.
Thanks!

is the '-20' in bytes ?
in PUBLIC/COMMON/OAK/INC/pkfuncs.h
#define PRETLS_THRDINFO -5
#define UTLS_INKMODE 0x00000001 // bit 1 set if in kmode
#define IsThrdInKMode() (UTlsPtr()[PRETLS_THRDINFO] & UTLS_INKMODE)
this must be the bit that is set when calling 'SetKmode();'

Yeah, the -20 is in bytes. Here's the disassembly of what I was looking at:
00B5EC E59F6068 LDR r6, &0000B65C
00B5F0 E59F5060 LDR r5, &0000B658
00B5F4 E5960000 LDR r0, [r6, #0]
00B5F8 E5101014 LDR r1, [r0, #-20]
00B5FC E3110001 TST r1, #1
00B600 15950000 LDRNE r0, [r5, #0]
...
00B650 F000BF08 ANDNV r11, r0, r8, LSL #30
00B654 01FC6758 MVNEQS r6, r8, ASR r7
00B658 01FC6760 MVNEQS r6, r0, ROR #14
00B65C FFFFC800 SWINV &FFC800 <-- Points to KDataStruct
What you said makes sense, yet it seems kind of strange that this API would be looking at an offest of -20.

so what you are seeing, is a call to 'IsThrdInKMode()' .
there is a space of thread local storage used by the kernel, just before the publicly accessible thread local storage. - look for SIZE_PRETLS, and PRETLS_RESERVED in the wince source.
this function ( well implemented as a macro actually ) is not a very strange function to call from a system call.
btw, you should have a look at IDA from datarescue. it will give you a much more readable disassembly. the stuff in your example from 00b650-b65c will be recognised as a constant pool, and the references to it, like at 00b5ec will be disassembled as 'LDR r6, =0xffffc800'

The only problem I have with IDA is that I can't afford it and their demo doesn't handle ARM processors. The generated output was done with a fairly simple program and has forced me to learn quite a bit about the underlying code in the OS. I've had to go back and forth between the disassembly and the shared source, but I've managed so far (with this exception).
I do have one other question while I have your attention. I've managed to inject a dll into all of the running processes and I've successfully managed to intercept several APIs by patching an application's IAT (and all attached modules, too) in an attempt to provide a better color handler for the system. It appears, however, that some programs, like Gwes.exe, don't use call my functions, but instead call the functions built into Coredll. For example, the GetSysColorBrush I mentioned earlier. This is what prompted me to begin reverse engineering Coredll in the first place. Do you know if the addresses are being stored somewhere? If so, that would explain why even though I've patched the IAT that the original function is still being called.

contact me in PM, I can help with IDA 4.51 full

gwes.exe is the program implementing the API, so quite likely it either calls it's api's directly, or calls the systemcalls directly.
and maybe someprograms are linked to a statically linked version of coredll?
a while back I experimented with trapping systemcalls, by modifying the method table in an API. ( see hookapi.cpp )
I do remember that my device became very unstable. so I guess that it somewhat worked, but haven't figured out what exactly I did wrong yet.
btw, I would be quite interested to see your code to trap calls via the IAT.

When you have a look to romimage.exe source code in platform builder you will notice that there is a special handling for coredll.dll.
All programs included in the MODULES section will directly resolve calls to coredll.dll. Only if you build a new XIP section a warning will appear "missing coredll.dll ... will late bind".
This means that a hook to coredll.dll will not be visible for in ROM programs since they will call the system functions directly (without the trap).
John

itsme said:
btw, I would be quite interested to see your code to trap calls via the IAT.
Click to expand...
Click to collapse
Unfortunately, I'm not at the computer where I have the code, so I'll have to upload it to you tomorrow. However, it involves extracting the IAT from the PPROCESS structure of a given program, then enumerating through the entries until I find the API I'm looking for. It's actually pretty straight forward. Give me your email address and I'll send it to you as soon as I can.
JohnSmith said:
When you have a look to romimage.exe source code in platform builder you will notice that there is a special handling for coredll.dll.
All programs included in the MODULES section will directly resolve calls to coredll.dll. Only if you build a new XIP section a warning will appear "missing coredll.dll ... will late bind".
This means that a hook to coredll.dll will not be visible for in ROM programs since they will call the system functions directly (without the trap).
Click to expand...
Click to collapse
I don't have the full source code, only what's available in the shared source, so I'm not sure what modules would be affected. However, I'm really only interested in a few of the Gwes APIs. I know it's possible at least at some point to hook into those as I've seen it done, though the individual who did it is under an NDA and can't tell me how he did it.
Itsme's process looks to be about the best so far, assuming I can get it to work. The only thing is that I need to find a way to translate the physical address to a virtual adress (and vice-versa) for MIPS, SH3 and the emulator, not just the ARM/XScale processors. If I could do that, then I might be able to get things to work.
Thanks for all of your help so far. I appreciate the time you have spent in explaining a few things to me.

[email protected]
for translating physical to virtual you would need to find the translation tables for each process, which I assume must exist somewhere, but have not found them yet. - my guess is it may be the 'pPTBL' entry from the process struct, but have not verified this yet.
( you know that virtual addresses can not uniquely be translated back to physical without knowing what process they are for? for instance the virtual address 0x11000 is visable in each process, and mapped to a different physical address each time. )

Fortunately, I've written an OS before, so I know what you mean about address mapping. If the pTBL does contain the page mappings, that would make sense. I found it easier in my OS to keep the TLB entries with the process they belonged to. That way the OS wouldn't have to search through its memory chain looking for the process's mappings.
Also, if the pTBL does contain the TLB entries, then it should be relatively easy to decode the addresses. After reading your code, itsme, I determined that the CINFO structure holds a pServer field which points to the process which contains the APIs. So, for example, the GDI and USER API sets are being held in Gwes.exe (at least, according to the pServer field). The ppfnMethods field is a VA referring to the pServer. If pServer is NULL, then the ppfnMethods field seems to be a PA. So, what I could do is check for pServer. If it is NULL, I could use the current process's pTBL structure to map the PA to a VA. If the pServer field is non-NULL, then I could try the pServer's pTBL field to do the mapping and then do the replacement that way.
If this works, I owe you big!

here is another experimental program, that investigates all the handles present in the system.
I used it to generate this overview of handles.

Progress So Far
I just thought I'd post an update on my progress so far. It appears that I can overwrite the API table pretty easily. Instead of taking a physical address, the table takes a pointer to a function in virtual memory. You just need to map it to slot 0 using MapPtrToProcess.
I've come across two issues in doing this. The first thing is that I can't call the original function address. For example, I store the original address contained in ppfMethods[x] and then attempt to typecast it to the proper function type, passing the incoming variables.
The other issue is that it appears that the API table is NOT refreshed upon a soft-reset. Fortunately, I was playing around with it on the emulator. Had I not, I would have been forced to hard-reset my device.
Does anyone have ideas on either of these issues?
Thanks again for your help so far!

a thing that just occurred to me, is that if you duplicate the apiset struct, the memory pointed to by ppfnMethods should be readable from the process specified in pServer.
so you should allocate the memory in the address space of pServer.
or set pServer to yourself, and add some hook code which does not modify the stack, so you can just pass most calls directly to the original server.
to call the original function address, you have to somehow switch process context, and then call it.

Well, in the case that I tested, I replaced the QueryAPISetID API which exists in Wn32 and therefore has no pServer. It appears that if there is no pServer, then there is no context switch needed. I've been able to verify that the API will execute my code and the generated assembly does not modify the stack in any way.
This one is really weird. Thanks for the suggestions.

chmckay said:
itsme said:
btw, I would be quite interested to see your code to trap calls via the IAT.
Click to expand...
Click to collapse
Unfortunately, I'm not at the computer where I have the code, so I'll have to upload it to you tomorrow. However, it involves extracting the IAT from the PPROCESS structure of a given program, then enumerating through the entries until I find the API I'm looking for. It's actually pretty straight forward. Give me your email address and I'll send it to you as soon as I can.
Click to expand...
Click to collapse
Hi,
Just wondring if you could post/PM/email me the code that lets you replace the API call. This is for the purpose of hooking a different DLL to do my own thing, or see here:
http://forum.xda-developers.com/viewtopic.php?p=131857#131857

I just sent you a PM with the information you requested.

Related

Injecting Assembly Code

I was wondering if anyone here could help me out.
I have a need to intercept a couple of GDI apis. At this point, I can successfully inject a library into GWES and hook the apis using the api set data structure contained in the kernel's memory (i.e. KDataStruct->aInfo[KINX_APISETS]). However, this doesn't work when Gwes calls the api internally.
So, I came up with a method that allows me to "hook" the api, similar to the way Detours works. What I did was allocate 8 bytes of virtual memory and copy the first instruction of the api to the first 4 bytes of the memory block. Then, I created an ARM branch instruction to jump from the second 4 bytes of the buffer to the second instruction in the original api, kind of creating a trampoline function. Then, I created one more branch that jumped to my new function and overwrote the first instruction of the original function.
Basically, this is what ends up happening:
The api is called
The function branches (unconditionally) to my function
My function calls the trampoline function
The trampoline executes the first command of the original function (the one that was overwritten) and branches unconditionally to the original function
The original function does its thing and returns to my function
My function handles whatever it needs and returns to the caller
Now, here's the problem. On my handheld, it works flawlessly. However, this code did NOT work on several other devices, causing freezes and hard-resets. I was wondering if anyone knows what I can do to get this fixed.
Here's how I calculate a branch:
branch = (((dest-source-8)>>2)&0xffffff)|0xea000000;
I've verified that all of the values come out correctly for the ARM specifications.
If anyone can help, I'd really appreciate it.
Thanks!
3 ideas. First is dumb. Maybe these devices keep GDI code you are trying to patch in ROM?
The second idea. Maybe the GDI code is mapped to every process address space without any modifications, and when your hook is called, some of the processes does not have your injected code in them and jump goes to unexistent address -> crash. You may try to use a jump command that uses full 32 bits of adress and a MapPtrToProcess() function to get your address that is visible in every proccess. In this case you should patch 8 bytes of hooked command.
The third idea. Are you sure that the patched bytes does not contain instructions that use PC-relative offsets? In this case you'll have to emulate them manually.
Well, all GDI/USER functions exist in Gwes.Exe. When you call something like BeginPaint, coredll transfers control to Gwes, Gwes makes the function call and control returns to the application. So placing a hook in Gwes is the best location.
On the ARM/Xscale platform, all branches are relative to the PC. My example in my first post shows how the branch offset is calculated. Each branch must be within 32MB (24-bits). The first instruction of the function I'm hooking, according to IDA, is an STFMD.
So, I thought that my original problem was that the jumps were more than 32MB away. However, I've confirmed that this is not the case in any of the crashes, which is why I'm confused.
I believe I wrote everything to ARM specifications, but I guess not. If it will help, I xan post some of code for a reference.
instead of a jump, maybe use
Code:
04 F0 1F E5 LDR PC, [PC-4]
xx xx xx xx DCD jumptarget

Protect You SOFTWARE

I know it is almost impossible to produce a software that is fully protected. In this I would like to share my experience in protection.
I developed a program that works in PPCPE and I have made a very good protection system….. I think
The protection system works as fallows:
- when the software is first install it capture the date of the installation
- it reads the device ID
- it ask the user for the program serial number
- I have two way of registering the system either through an SMS or through the web using a GPRS.
- The software combines the three number together using some equations to make it almost impossible to find out what I am collecting… also I use an equation verify if the serial number is OK since we are using SMS and it is very costly to send SMS that contains a wrong serial number
- When the user chose the method to register the number is send to my server and the server send back the activation key to the user PPCPE
- The PPCE will read the SMS and delete it and store this SMS in the database …
The above is to get the activation key
In the software the activation key is produce and I use “if statement” to compare the activation key which is stored in the data base and the one the software produce if they are the same it will execute otherwise it will stop execution
To make it very difficult for the hacker I use pointer in the program and in these pointer I add the protiction key to it and subtract the key the program produce to make the additon equal to zero if the two key are the same
The pointer point to each button and each menu item in the program
I hop this information will help and I welcome any comment
Hmmm, sounds nice...but is it worth all the trouble...especially the SMS route could complicate things, no?
Besides, with good debuggers is it not possible to NOP the check section or jmp it, applying a patch?
I would opt more for a good packer such as Armadillo, and protect it that way. It will obfuscate the code, has debugger protections built-in, splits codes and destructs IAT. Additionally, you could add nanomites to make unpacking even harder. Then use a simple license key system.
Yes you are write .. a good hacker can do that …. But
If you use the method of pointer it is almost impossible to get any thing out of the program and it will be use les for any body to use it
And also it is almost imposable to hack it
But armadillo is only available for x86 Windows. But your message is right, HappyGoat.
pointer protection: piece of cake!
Well, the pointer thing as you describe it does not sound too difficult to hack.
You said your software will take the address for a pointer, add the key the user has entered, and substract the one the program has computed so that it equals to zero.
So, this means that the shift is always the same, so if you can get the entry point for any button, you know which value to add to the key generated by your software. Since you don't obfuscate the code this is a matter of minutes to hack this. :roll:
UL
Re: PROTICT YOUR SOFTWARE
As an old cracker I can tell you that this algo would not be difficult to crack. You are not using EXE file encryption, anti-debugging, integrity checking, and other tricks that are used in good protections like ASProtect. They would take some hours to bypass. And playing with pointers can stop only kiddies. UnlockMe said why.
If a cracker would get one valid question-answer pair, he'll easily convert any program to a fully working version. And your code can be cracked without this knowledge.
- The software combines the three number together using some equations to make it almost impossible to find out what I am collecting…
Click to expand...
Click to collapse
Funny. Why should the cracker try to "find out what I am collecting"? Why the cracker should be bothered with all this ****? There are easier ways.
also I use an equation verify if the serial number is OK since we are using SMS and it is very costly to send SMS that contains a wrong serial number
Click to expand...
Click to collapse
Costly SMS? Even in Russia you can get free SMS subscription. I have free SMS + free GPRS + free incoming calls.
Your protection has at least one very thin part that makes it useless. I've seen the similar ideas before. But I would not tell you
And remember:
If it runs, it can be defeated. (c) +Orc
Click to expand...
Click to collapse
It is very nice to see people participates in a subject. I find it very interesting. And very helpful
I am not going to tell what I do but I am given a point to start to programmer
Chatty
Thanks for bringing this point. I can not find it also
UnlockME
I think it is very difficult to hack.
Imagine in my software I have 36 button and menu item. Each of them has a pointer. Let us say button one has a pointer value equal to 11675 let say it is stored in ptr
My key is 123456789 .. let say it is stored in a string str1
The key in the program is 908070605040302010 …… I use more encryption than that but this is just a demonstration
And let us say it is stored in str2
When you address the button you address it like this
Ptr = ptr – (str1[1]-str2[17])
As I mention I am not going to reveal the protection that I use.. I am only giving a point to start
There is more thing in it I leave it to your imagination ..
Mamaich
In my country each SMS cost the mobile owner 0.1 USD … I am not going to cost hem moony for a wrong entry
…….
I think I know what you are thinking …. If the key is produced in the program I can hack it … I hope the above example clear thing up
……..
if you know any EXE encryption or anti debugging software I will be thankful
……..
thanks every body for your replay
-------------------------
pleas remember I am not Claiming that my sAlgorithm is anti-hacked …. It is only an algorithm for protection that I came with
wwb95, I'm not going to disclose in this forum how to actually hack an exe, but what i can tell you is that pointer-based protection will only stop kiddies as Mamaic says.
a hacker is not always a bad guy, though often they use their knowledge for such purpose, but it is before everything a guy that has an extensive knowledge of development tools, operating system, memory management, ...
I can tell you that if you are going to protect your software with this pointer thing, please send me a link I'll be only too happy to provide it for free to the community with a working "yes-code". 8)
wwb95 said:
When you address the button you address it like this
Ptr = ptr – (str1[1]-str2[17])
Click to expand...
Click to collapse
I'll assume that (str1[1]-str2[17]) is always a constant for all Ptrs. Then you can easily find an original button handler (don't ask me how, newbies can check all function addresses, gurus can just look at the code, I'll use a different method), calculate this value and patch a program or write a keygen. And if it is not a constant - the process would not be much more difficult.
if you know any EXE encryption or anti debugging software I will be thankful
Click to expand...
Click to collapse
I don't know any existing protection. Long time ago I was developing such a project, but due to a lack of time and no investitions I've dropped it.
Here is a crackme - http://mamaich.kasone.com/wz/crackme.rar
and a pre-aplha of protector - http://mamaich.kasone.com/wz/protector.rar
It can compress&encrypt ARM WinCE DLLs and EXE files, has minor anti-debugging tricks and primitive import/export/resources encryption. And thats all that was done. No API, no stolen bytes, no on-the fly decryption, no integrity checking, etc.
I would not publish its source codes nor continue the work.
My advice: give up trying to protect your app. It can't be done; anything can be cracked easily. You're only going to piss off your users when the complex reg scheme starts introducing bugs and instability.
All you really want to do is a simple registration scheme. You have to rely on people's honor.
At Airscanner we wrote a book showing how to crack software, with a couple of chapters on ARM-based cracking for Windows CE. But you can get more info, and better, for free at Kaos' website:
http://ka0s.net/
It has everything you need to get started in Pocket PC reverse engineering.
By the way, it's good to see +ORC referenced in this forum. Mamaich do I know you?
airscanner said:
By the way, it's good to see +ORC referenced in this forum. Mamaich do I know you?
Click to expand...
Click to collapse
Some time ago I was a regular poster on www.reversing.net and www.reng.ru and reader of fraviamb. Now I don't have time for that.
Maybe you've seen my name in "thanks" sections of some tools.
ZXEvil why are you posting that link on multiple topics? What is that file?

name garbaling in dll

I am using some functions in a dll but the only way I can get the name of the function to remain as I name it is to make it extern "c". If I do not do this then I have to copy the name from directly inside the dll and put the garbled text in my code, ed "someFunctionName" ends up "[email protected]@YAHXZ". It seems that every example I ever see dose not have this problem. Is there some setting I do not know about to force the linker to use the names I type without using a def file?
It was my understanding that this has something to do with C++ convention and cannot be changed, though I could be wrong on this point and if so, would also like to earn the answer.
Mean while if you are using functions from your DLL in your own code you can link to it "implicitly" (am I confusing the terms here?) by simply linking in the lib file compiler creates for the DLL and using the regular function names without all the garbage.
I think that what I am seeing is microsoft ("decoration") not from c++. I think the c++ name mangaling follows some rules that let it show the size of data being passed as arguments.
I do not want to link to it and use .lib etc because I do not want my main project to be entangled with the dll. I am trying to make a pluggin so it will be dynamically loaded with loadlibrary and getprocaddress. I am a bit new to this but it seems to work ok, I was just not sure how to use the def file properly. For example what are the rools regarding the order of names in the def as compared to the header file and what about variables, are they exported or do I have to have a function that returns a pointer to them.
Well some of MS help I encountered states that DEF files are obsolete, or at least MS is trying to make them so.
I didn't get deep in to the DLL rules my self but from what I understand it is sufficient to declare a function as _dllexport for it to be seen from the outside. If you want to specific ordinals (like in the plug-in case) that's another matter.
Variables can be exported and so are classes. I never tried using it, but the "hello world" example of a DLL that eVC 4 builds exports a function a class and a variable and does not use DEF file.
and after building that automatically generated code I get a dll with decorated function names (I view the dll in notepad to check). At first I could not figure out what was going on but after I put the decorated names into getprossaddres it works.

Simple Programming Question embedded VC++

I'm currently doing some programs myself with the free MS embedded VC++.. and I'm finding it comfortable to do a simple dialog-based programs for PPC. I think I can have most of the background code going, and I've just got the GUI .. alright.
Now the question, how do I do a copy/paste to/from clipboard? I had most of the stuff done using the included MFC Wizard. I can get and send data to/from an EditBox (TextBox, whatever you call it). However, the click-hold thing on PPC doesn't seems to work on my EditBox, and hence I'm thinking what's needed to enable a simple Copy/Paste on an EditBox.
Currently, I'm using the simple
Code:
m_editBox = _T("the message I want to show");
UpdateData(FALSE); //send it to the EditBox
Any guide from here would be appreciated. However, I'm thinking there may not be an easy way to do that, hence I've also tried adding a 'Copy' and 'Paste' button to do the job, but I've tried things like
Code:
SetClipboardData(x, x)
GetClipboardData(x)
None works.
I have also tried
Code:
COleDataObject DataObject;
and with the handle etc etc .. but I can't seems to find this COleDataObject , is that in some other environment (e.g. not PPC env)?
Help
Fast solution:
http://www.pocketpcdn.com/articles/sip.html
(this shows/hides sip on get/lost focus in edit controls and add the context menu too)
and this is a simple example how to copy datas into clipboard
if(OpenClipboard(NULL))
{
EmptyClipboard();
HLOCAL clipbuffer = LocalAlloc(0, 100);
wcscpy((WCHAR*) clipbuffer, (WCHAR*) (vtNumber.bstrVal));
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
free(szMsg);
LocalFree(clipbuffer);
}
I hope this help u
bye
Thanks for your respond.. things work.. a bit
Code:
//put a test char
char *test;
test = (char*) malloc(100);
strcpy(test, "blah blah blah");
//codes you've given
if(OpenClipboard()) //OpenClipboard(NULL) gives me error
{
EmptyClipboard();
HLOCAL clipbuffer = LocalAlloc(0, 100);
wcscpy((WCHAR*) clipbuffer, (WCHAR*) test);
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
//free(szMsg); //not sure what 'szMsg' is
LocalFree(clipbuffer);
}
Things somewhat works. I'm not really sure which part I've got wrong. I'm suspecting some memory allocation is giving me problems. The thing is, if I were to use 'CF_UNICODETEXT' on the 'SetClipboardData(x,x)' line, I get something to paste on other programs (PPC Notes). BUT, the thing pasted is some funny stuff (e.g. letters that cannot be rendered, hence I get the little squares). If I were to use 'CF_TEXT', I don't seems to able to send my stuff to the clipboard or it made it invalid for (PPC Notes) pasting (e.g. I'm not able to paste it in PPC Notes).
Thanks.
BTW, if you are in the mood, can you give me a Paste function as well. Thanks a bunch.
Hi hanmin.
Odd I didn't notice this thread sooner.
Any way if you still having problems with this code here is the solution:
You are working with char and strcpy so your text is in ASCII (each letter one byte).
But you are calling SetClipboardData with CF_UNICODETEXT so it expects WCHAR (UNICODE) where each letter is two bytes.
The strange letters are the result of two consecutive bytes being interpreted as a single letter (probably lends you in Chinese or Japanese region of the Unicode table)
Windows mobile doesn't usually work with ASCII so the text you get from the edit box will already be in Unicode and won't give you any trouble.
The code should look like this:
Code:
//put a test char
CString test; //since you are working with MFC save your self the trouble of memory allocation
test = L"The text I want on clipboard"; //The L makes the string Unicode
//codes you've given
if(OpenClipboard()) //OpenClipboard(NULL) gives me error
{
EmptyClipboard();
//not sure why you need to copy it again, but here goes:
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2); //remember: every letter 2 bytes long!
wcscpy((WCHAR*) clipbuffer, (WCHAR*)(LPCTSTR)test); //LPCTSTR is an overloaded operator for CString
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
//szMsg probably belongs to some larger application and is irrelevant
LocalFree(clipbuffer);
}
I never used the clipboard APIs my self so I can't guide you farther but this code should work.
Hope this helps.
Wooo hooo.. Thanks levenum. I'm back on business!
You code works wonderfully.. just the final code "LocalFree(clipbuffer);" seems to cause problems. Without that, it works. I'm not sure if it will cause a memory leak.. but that's not much of my concern now
Now my Paste also works, and it seems that the magic code is the "LPCTSTR", which I have NO idea what it is (I'm more of a pure C person and.. a Java person ) Thanks again.
Glad I could help.
I am working from Ubuntu right know (Linux distro in case you didn't know) so I do not have access to my off-line MSDN files, but I recommend you check out the documentation for SetClipboardData.
It is possible it releases the memory it self so when you call LocalFree the handle is no longer valid.
That could also be the reason why you need to allocate memory instead of passing it the string directly.
As for LPCTSTR it is simple and not C++ related:
#define const* WCHAR LPCTSTR
Its M$ way of saying Long Pointer to Constant STRing
T changes meaning based on what you are working with:
If you work with ASCII TCHAR is char
If you work with Unicode TCHAR is WCHAR
Basically these are just all redefinitions of variable types so you can distinguish what they are used for.
In C++ you can overload operators. For example you can have a function which changes the way ++ works with certain types of variables.
In our case CString class has a function which determines what happens when you try to cast (convert) it to a pointer to string.
Thats all the "magi" code.
Good luck with your app.
Small update:
Since I had to go in to XP anyway (to change PDAMobiz ROM which kept hanging at random and didn't let me use BT to latest PDAViet which for now seem very good) I took a quick peek at the help files.
Here is why you should not release the memory:
After SetClipboardData is called, the system owns the object identified by the hMem parameter. The application can read the data, but must not free the handle or leave it locked. If the hMem parameter identifies a memory object, the object must have been allocated using the LocalAlloc function
Click to expand...
Click to collapse
levenum, thanks. You've got me almost there. There are several stuff I need to polish up though. Attach is a pre-mature version of what I wanted to do. There are several issues (including the fact that, only the 4 characters of the password are effectively used, which can be easily fix, I think. Just need to find the bug and squash it) that I like to polish up. They are sorted in order of importance (to me):
[1] Keyboard (SIP) pop up.
For this, I digged around and got to know that the function
"SHSipPreference( HWND, SIP_UP)" is the one to used. However, it never did what it suppose to do. I have had it put inside the "OnSetfocusConfirmPasswordEdit()" of the edit box, which should be called when it is set focus. I suspect that is I haven't set the HWND correctly. I have tried "NULL" and also tried using the "CWnd* pParent" from my dialog constructor (generated code my MFC Wizard). None of them worked.
[2] Editbox focusing.
For some reason, the focus on my main-dialog is correct on the editbox of the 'message'. However, on the dialog which is to confirm the password (which I called using
Code:
CConfirmPasswordDlg confirmPasswordDlg;
int nResponse = confirmPasswordDlg.DoModal();
is focusing on the 'Ok' button. What I like it to do is to focus on the 'confirmPasswordEdit' box, and it ought to automatically pop up the keyboard (SIP).
[3]Reduced size pop up dialog
I was trying to make the 2nd confirm password dialog smaller, something like a pop up in the PPC rather than something that take up the whole screen without much contents in it. How would you go about doing that? Is it not possible in PPC? E.g, if you were to use Total Commander, and start copying files around, they do have a pop up that does take up the entire screen. I'm suspecting I shouldn't do a "confirmPasswordDlg.DoModal()", and should some what do something myself. I have tried, SetVisible(1) thing, but that doesn't work. Or it shouldn't meant to work because my 1st screen is a dialog screen?
[4]Timer?
I would like to have a function of which after a certain period of idle time, it will clear off the clipboard and close itself. How would I go about doing this? Some sort of background thread thing?
Anyone can shine a light on my issues above? On MS-embedded Visual C++ (free), with Pocket PC 2003 SDK (free)
Attached the Blender-XXTea edition
Works on PPC2005 and WM5 (should work on WM6)
Does not require .NET framework
VERY small (54K)
hanmin said:
[2] Editbox focusing.
For some reason, the focus on my main-dialog is correct on the editbox of the 'message'. However, on the dialog which is to confirm the password (which I called using
Code:
CConfirmPasswordDlg confirmPasswordDlg;
int nResponse = confirmPasswordDlg.DoModal();
is focusing on the 'Ok' button. What I like it to do is to focus on the 'confirmPasswordEdit' box, and it ought to automatically pop up the keyboard (SIP).
Click to expand...
Click to collapse
In your CConfirmPasswordDlg::OnInitDialog handler, call GetDlgItem(confirmPasswordEdit).SetFocus() and return FALSE. That should handle the focus and possibly the SIP popup.
3waygeek said:
In your CConfirmPasswordDlg::OnInitDialog handler, call GetDlgItem(confirmPasswordEdit).SetFocus() and return FALSE. That should handle the focus and possibly the SIP popup.
Click to expand...
Click to collapse
HEY! The focus works! The working code is
Code:
((CWnd*) CConfirmPasswordDlg::GetDlgItem(IDC_CONFIRM_PASSWORD_EDIT))->SetFocus();
BTW, I'm wondering, whats the effect of a return TRUE/FALSE on a 'OnInitDialog()'?
Anyway, the keyboard pop up is still not working. I'm using the command
Code:
void CConfirmPasswordDlg::OnSetfocusConfirmPasswordEdit() {
SHSipPreference( (HWND)g_pParent, SIP_UP);//
}
which I suspect the 'g_pParent' is NULL. If it is NULL, would it work?
Ok, I haven't used MFC for a while and almost not at all on PPC but I will give this a shot:
1) MFC forces dialogs to be full-screen. Here is a detailed explanation on how to change that. Note that for some reason this will work only once if you use the same variable (object) to create the dialog several times.
If you use a local variable in say a button handler thats not a problem because the object is destroyed when you exit the function.
2) There is a simple SetTimer API. You can give it a window handle and then add an OnTimer message handler to that window. Or you could give it a separate function which will be called (say TimerProc). In that case you can give it NULL as window handle.
Note that CWnd objects have a member function with the same name (SetTimer) which sets the timer with that window handle (so that window will receive WM_TIMER message). If you want the raw API call ::SetTimer.
Also note that the timer will continue to send messages / call your special function every x milliseconds until you call KillTimer.
3) I am not sure what the problem with the SIP is. CWnd and derived classes like CDialog have a function called GetSafeHwnd (or GetSafeHandle, I don't remember exact name). Try passing that to SHSipPreference.
If that does not work here is an article with an alternate solution.
WOHO!! Everything works NOW!!.. MUAHAHHAHA.. wait til you see my release version
Non maximized windows works using the code suggested at the page. Although I still do not understand where the heck this '.m_bFullScreen' property came from. It is not anywhere obvious to be seen.
Code:
CNfsDlg dlg;
dlg.m_bFullScreen = FALSE;
dlg.DoModal();
Timer works using the
Code:
xx{
//your code...
CBlenderDlg::SetTimer(1, 5000, 0); //event 1, 5 seconds, something
//your code...
}
void CBlenderDlg::OnTimer(UINT nIDEvent){
//do something here for the timer
}
although somehow, the OnTimer() only works if I went to the MFC class wizard to add the WM_TIMER function. Doesn't work when I add in the OnTimer() myself. Must be something else that I've missed. Anyway.
Keyboard issue solved using
Code:
SHSipPreference( CBlenderDlg::GetSafeHwnd(), SIP_UP);
Glad its working out for you.
Couple of comments:
1) Somewhere at the top of the cpp file, if I am not mistaking there is something called a message map. It's a bunch of macros that lets MFC know what window messages it handles. An entry there is what was missing when you added the function manually.
2) m_bFullScreen is just another among many undocumented features. M$ likes to keep developers in the dark. For instance WM 2003 and up have an API called SHLoadImage which can load bmp, gif, jpg and some other formats and return HBITMAP which all the usual GDI functions use.
This API was undocumented until WM 5 came out and even then they said it only works for gif...
hanmin said:
BTW, I'm wondering, whats the effect of a return TRUE/FALSE on a 'OnInitDialog()'?
Click to expand...
Click to collapse
The return value indicates whether or not the standard dialog handler (which calls your OnInitDialog) should handle setting the focus. As a rule, OnInitDialog should return TRUE, unless you change the focus within the handler (or you're doing an OCX property page on big Windows).
I haven't done much WinMob/CE development -- I've been doing big Windows for 15+ years, so window message handling is pretty much second nature. I started doing Windows development back in the days when you didn't have C++ or MFC boilerplate; you had to implement your own DialogProc, crack the messages yourself, etc. It's a lot easier now.
CommandBar / MenuBar
I'm back.. with more questions
Not much of a major issue, but rather an annoying thing I've found. Probably that's what evc/mfc/m$ intended to do that.
Anyway, I'm starting my way of getting around CommandBar. I created a MFC skeleton, studied the code, and that's what I've found, after I've created a CommandBar/MenuBar on evc and putting it in
Code:
if(!m_mainMenuBar.Create(this) ||
!m_mainMenuBar.InsertMenuBar(IDR_MAINMENUBAR) ||
!m_mainMenuBar.AddAdornments() ||
!m_mainMenuBar.LoadToolBar(IDR_MAINMENUBAR))
{
TRACE0("Failed to create IDR_MAINMENUBAR\n");
return -1; // fail to create
}
where I have the variable 'CCeCommandBar m_mainMenuBar' and I have created a MenuBar on evc with the Id 'IDR_MAINMENUBAR'. The menu bar works flawlessly on my dialog based application, when I have the 1st level as a pop up. Example
MenuBar --> 'File' --> 'New', 'Save'
Where 'File' is a folder-like thing that pop-ups and show the contents (i.e. in this example, 'New', and 'Save'). However, given the SAME code to load the CommandBar/MenuBar, it will not work, if I were to put the actual command at 1st level. Example, this will not work
MenuBar -> 'New', 'Save'
where there isn't any folder-like pop-up to store the commands 'New', and 'Save'.
I know that I can have buttons for these commands, and probably works. But, what I'm trying to do is to utilize the bottom-left-right softkey in WM5/6. If I were to have the 'File'->'New','Save' structure, it works fine with WM5, showing it as a softkey. But, if I were to do just 'New','Save' it will not show up in both WM2003 emulator and WM5.
As a matter of fact, even if I have (say) File->New,Load, and I added a new command (i.e. not folder-like-pop-up), example 'Help' on the CommandBar/MenuBar, the File->New,Load will not show up too. It seems like the 1st level command (ie. without a folder-pop-up), causes some problems and stop it from loading further.
Guys, ring any bell?
two bytes more
levenum said:
Hi hanmin.
Odd I didn't notice this thread sooner.
Any way if you still having problems with this code here is the solution:
You are working with char and strcpy so your text is in ASCII (each letter one byte).
But you are calling SetClipboardData with CF_UNICODETEXT so it expects WCHAR (UNICODE) where each letter is two bytes.
The strange letters are the result of two consecutive bytes being interpreted as a single letter (probably lends you in Chinese or Japanese region of the Unicode table)
Windows mobile doesn't usually work with ASCII so the text you get from the edit box will already be in Unicode and won't give you any trouble.
The code should look like this:
Code:
//put a test char
CString test; //since you are working with MFC save your self the trouble of memory allocation
test = L"The text I want on clipboard"; //The L makes the string Unicode
//codes you've given
if(OpenClipboard()) //OpenClipboard(NULL) gives me error
{
EmptyClipboard();
//not sure why you need to copy it again, but here goes:
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2); //remember: every letter 2 bytes long!
wcscpy((WCHAR*) clipbuffer, (WCHAR*)(LPCTSTR)test); //LPCTSTR is an overloaded operator for CString
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
//szMsg probably belongs to some larger application and is irrelevant
LocalFree(clipbuffer);
}
I never used the clipboard APIs my self so I can't guide you farther but this code should work.
Hope this helps.
Click to expand...
Click to collapse
I know it is a bit late! But there is a mistake the code snippet:
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2); //remember: every letter 2 bytes long!
needs to be
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2+2);
the terminating 0 is als 2 bytes long!
Those errors are sometimes fatal, with very less chance to find them!
ms64o

C++: open file for writing in the LocalStorage

Hi guys, could you tell me how to open file for writing in the phone app LocalStorage for the non-unlocked handset (regular app for store)?
Code below doesn't work
Code:
FILE *tmp;
auto tmpPath = Windows::Storage::ApplicationData::Current->LocalFolder->Path + "\\tmp.txt";
auto tmpErr = _wfopen_s(&tmp, tmpPath->Data(), L"w");
Any suggestions?
Try looking though msdn articles. I found it somewhere in there. But I have forgotten it now.
Sent from Board Express on my Nokia Lumia 1020. Best phone ever!!
Note to noobs: DON'T PM ME WITH QUESTIONS. POST IN THE FORUMS. THAT'S WHAT THEY ARE HERE FOR!
@wcomhelp, please keep your rtfm advices for yourself, OK? I'm not a noob and of course I've searched msdn, google, codeplex, github etc. and so on before posting here. If you don't know how, much better be silent (like others who read this post but have no idea what I'm talking about)
I've tried a few possible methods including ugly "MS-way" with task & lambda syntax (see below) but nothing worked as it should be (code below works if no file exist and fails if file already exist - CreationCollisionOption::ReplaceExisting options is not worked/not implemented/buggy/billgates_knows_only ).
Code:
auto folder = Windows::Storage::ApplicationData::Current->LocalFolder;
Concurrency::task<Windows::Storage::StorageFile^> createFileOp(
folder->CreateFileAsync(CONFIG_FILE_NAME, Windows::Storage::CreationCollisionOption::ReplaceExisting));
createFileOp.then([=](Windows::Storage::StorageFile^ file)
{
return file->OpenAsync(Windows::Storage::FileAccessMode::ReadWrite);
})
.then([=](Windows::Storage::Streams::IRandomAccessStream^ stream)
{
auto outputStream = stream->GetOutputStreamAt(0);
auto dataWriter = ref new Windows::Storage::Streams::DataWriter(outputStream);
// data save code skipped
return dataWriter->StoreAsync();
})
.wait();
BTW, I've used workaround, to save ported C++ app data to the LocalSettings instead of text file (as it was in original code).
"Doesn't work" doesn't give us a lot to go on, troubleshooting-wise. Can you tell us what error you get?
Only thing I see in the code that looks a little weird is that the
Code:
"\\tmp.txt"
part isn't explicitly a wide-character string, but I'd expect string concatenation to take care of that.
Also, out of curiosity, why libc functions instead of Win32? Obviously, the code you're writing here isn't intended for much portability...
@GoodDayToDie, there is no error code at all - standard POSIX functions returns NULL FILE, the ::GetLastError() also return 0.
I'm porting old C-style app to WinRT platform and don't care about portability (but the first post code - just a simplified example, nothing more).
POSIX (libc) functions works pretty well for reading only but not for writing - that's the problem...
As I said before, I resolved my issue by workaround but still curious why the POSIX calls fails for file writing in the app storage.
buuuuuuuuuuuuuuuuh
No need for lambdas
https://paoloseverini.wordpress.com/2014/04/22/async-await-in-c/
You may also want to rethink your strategy
You can't create files at arbitrary locations, so your method is kinda redundant. All the locations you are allowed to create and read files to/from are available through KnowFolders and ApplicationData classes. These return StorageFolders which in turn can create files with CreateFileAsync (used for both creating and opening existing files) and get files with GetFilesAsync ( I recommend against this one though) and similar methods.
@mcosmin222, could you please re-read my posts one more time? I'm not trying to create files at "arbitrary locations"; I wanna create/write simple text file at the app's local storage (which one should be available for reading/writing). And the problem not in the lambdas or task usage (yes, it looks ugly but it works as it supposed to be).
Could you provide a working example instead of words? And I'll be glad to say you "thanks a lot"; can't say now...
sensboston said:
@mcosmin222, could you please re-read my posts one more time? I'm not trying to create files at "arbitrary locations"; I wanna create/write simple text file at the app's local storage (which one should be available for reading/writing). And the main problem not in the task (async execution).
Could you provide a working example instead of words? And I'll be glad to say you "thanks a lot"; can't say now...
Click to expand...
Click to collapse
Sure, just gimmie a few hours till I can get near a compiler that is capable of doing that
Of course, no rush at all, take your time. It's not a showstopper for me now (actually, my workaround with AppSettings is more preferable way - at least for universal app and roaming settings) but the issue still has an "academic interest" and maybe will be useful in the next projects for porting old C/C++ code to WinRT.
sensboston said:
Of course, no rush at all, take your time. It's not a showstopper for me now (actually, my workaround with AppSettings is more preferable way - at least for universal app and roaming settings) but the issue still has an "academic interest" and maybe will be useful in the next projects for porting old C/C++ code to WinRT.
Click to expand...
Click to collapse
hi
in vs 2015
#include <pplawait.h>
Something of the like should work
Code:
WriteSomeFile() __resumable
{
auto local = ApplicationData::Current->LocalFolder;
auto file = __await local->CreateFileAsync("some file", CreationCollisionOption::eek:penIfExists);
__await FileIO::WriteTextAsync(file, "this is some text");
}
However, as of right now, in VS 2015 RC, you have a host of limitations when dealing with this, but I do not believe this will be of any issue to you.
Code:
Cannot use Windows Runtime (WinRT) types in the signature of resumable function and resumable function cannot be a member function in a WinRT class. (This is fixed, but didn't make it in time for RC release)
We may give a wrong diagnostic if return statement appears in resumable function prior to seeing an await expression or yield statement. (Workaround: restructure your code so that the first return happens after yield or await)
Compiling code with resumable functions may result in compilation errors or bad codegen if compiled with /ZI flag (Edit and Continue debugging)
Parameters of a resumable function may not be visible while debugging
Please see this link for additional details
http://blogs.msdn.com/b/vcblog/archive/2015/04/29/more-about-resumable-functions-in-c.aspx
you should also note that this works with native, standard C++ types.
@mcosmin222, looks like unbuffered writing works (i.e. without streams) fine but it still not an answer for my initial question
I'm curious why the standard POSIX libc writing operations are not working on the app's local storage (but reading from files works fine). Actually, it's all about porting old C/C++ code for WinRT; of course for the new app it's not a problem but re-writing old code to FileIO should be a huge pain in the ass. What I did: I've "mechanically" changed all libc formatted outputs from file to string, and use LocalSettings class (actually it's XML file) to store that string (I'm planning also change LocalSettings to RoamingSettings, to provide settings consistency between WP & desktop app).
P.S. <pplawait.h> is not available in my VS 2015 (release pro version) so I've tested by using lambda pattern.
OK, first things first, LIBC != POSIX! The POSIX way to do this would be to call the open() function and get back an int as an "fd" (file descriptor), which is of course not implemented on Windows Phone because Windows Phone is not a POSIX platform (you might find the Windows compatibility functions _open() and _wopen(), but I doubt it). You are attempting to use the standard C library functions, which are portable but implement kind of a lowest common denominator of functionality and are generally slightly slower than native APIs because they go through a portability wrapper.
Second, sorry to be all RTFM on you but you should really Read The Manual (or manpage, or, since this is Windows, the MSDN page)! Libc APIs set errno (include errno.h) and use different error values than Windows system error codes (or HRESULT codes, or NTSTATUS codes, or...). Error reporting in C is a mess. If you were calling CreateFile(), you would check GetLastError(), but since you're calling _wfopen(), you check errno (not a function).
@GoodDayToDie, _wfopen_s returns 0 (i.e. "no error") but tmp pointer receives also 0 (NULL) Could you explain why libc file functions are working for reading (at the app installation & local data folders of course) but not for writing? Any logical ("msdn based") explanation? Or you just... don't know, heh?
sensboston said:
@GoodDayToDie, _wfopen_s returns 0 (i.e. "no error") but tmp pointer receives also 0 (NULL) Could you explain why libc file functions are working for reading (at the app installation & local data folders of course) but not for writing? Any logical ("msdn based") explanation? Or you just... don't know, heh?
Click to expand...
Click to collapse
LIBC functions will most likely work just in debug mode. The moment you try to publish the app it will fail. You can do lots of crazy stuff on your developer device with basic C functions, but if you try publishing, it won't pass the marketplace verification.
Most C APIs are simply not supported, since they do not comply with the sandbox environment of the Windows Runtime.
The code I gave you is tested with VS 2015 RC. You should be able to include <pplawait.h> just fine, if you are targeting toolchains newer than November 2013.
mcosmin222 said:
The moment you try to publish the app it will fail. You can do lots of crazy stuff on your developer device with basic C functions, but if you try publishing, it won't pass the marketplace verification.
Click to expand...
Click to collapse
Hmm... Are you sure or it's just your assumption? My app is still under development but (just for test!) I've made store app package for WP and it passed local store verification I also uploaded package to the store (via browser) and it also passed. I don't have time to create all tiles and fill all fields to complete beta-submission (actually, I don't know how to mark app as beta in the new dashboard) but for me it looks like app don't have any problem and will pass store certification easily. And you may be sure - it uses A LOT of libc calls 'cause originally it was written for Linux (or kind of UX system)
sensboston said:
Hmm... Are you sure or it's just your assumption? My app is still under development but (just for test!) I've made store app package for WP and it passed local store verification I also uploaded package to the store (via browser) and it also passed. I don't have time to create all tiles and fill all fields to complete beta-submission (actually, I don't know how to mark app as beta in the new dashboard) but for me it looks like app don't have any problem and will pass store certification easily. And you may be sure - it uses A LOT of libc calls 'cause originally it was written for Linux (or kind of UX system)
Click to expand...
Click to collapse
Once usage reports get up to microsoft, you will be given a notice to fix the offending API (happened to be once). You are much better off using the platform specific tools: not only they are much faster, they are also much safer and you won't have problems later on.
You might get away with reading stuff (since reading is not that harmful), but you should be using the winRT APIs each time they are available.
Simply uploading your app to the marketplace just reruns the local tests in their cloud servers: once you submit the actual app (not beta, not tests) for consumers, it will be much more aggressively checked. This is because the store allows specific scenarios for distributing apps in close circles that may break the usual validation rules.
@mcosmin222, one more time: is it your assumptions or personal experience? I don't know how many apps you have in store (I do have a lot) but I never heard that you said. I've used C++ libraries with WP hacks in some of published apps but never had any problem with "aggressive checks". What I know: if you are using some "prohibited" calls, your app will not pass uploading to the store (uploading, not a certification).
P.S. I'll send you personally a link when I publish release Hope, you'll like it
sensboston said:
@mcosmin222, one more time: is it your assumptions or personal experience? I don't know how many apps you have in store (I do have a lot) but I never heard that you said. I've used C++ libraries with WP hacks in some of published apps but never had any problem with "aggressive checks". What I know: if you are using some "prohibited" calls, your app will not pass uploading to the store (uploading, not a certification).
P.S. I'll send you personally a link when I publish release Hope, you'll like it
Click to expand...
Click to collapse
By "hacking" you mean recompiling the code to fit the windows phone toolchain? if so, then you shouldn't have to worry about too many things.
but even so, calling stuff like fopen in locations other than local storage will get your app banned. Even if it makes past the first publication, you can get noticed weeks later or even months (yes, it did happen to me personally).
In most cases, calling C APIs that can potentially break the sandbox (like opening a file in doc library with fopen) will always fail the marketplace verification, eventually. If it hasn't happened to you yet, then you may have not been using such APIs.
No, my C++ code is not accessing other than approved locations but the app has a lot of libс (and of course other C/C++ libs) calls; I'm 99.9% sure it's legitimate and will be not a source of any problem. Otherwise what is the advantages of having C++ compiler?!
As far as I know, just some of API's are prohibited but you will notice it right after local store compatibility test run...
As for "hacks" I mean usage of undocumented ShellChromeAPI calls (including loading hack).
P.S. I've found why <pplawait.h> header is missing. Initially I've created solution with the 12.0 toolset but now I can't (or don't know how to) change it to 14. However creating the new empty universal solution in VS 2015 also gives me toolset 12 by default. What is the toolset 14 for? Windows 10?
sensboston said:
No, my C++ code is not accessing other than approved locations but the app has a lot of libс (and of course other C/C++ libs) calls; I'm 99.9% sure it's legitimate and will be not a source of any problem. Otherwise what is the advantages of having C++ compiler?!
As far as I know, just some of API's are prohibited but you will notice it right after local store compatibility test run...
As for "hacks" I mean usage of undocumented ShellChromeAPI calls (including loading hack).
P.S. I've found why <pplawait.h> header is missing. Initially I've created solution with the 12.0 toolset but now I can't (or don't know how to) change it to 14. However creating the new empty universal solution in VS 2015 also gives me toolset 12 by default. What is the toolset 14 for? Windows 10?
Click to expand...
Click to collapse
The advantage of C++ is the obvious versatility: the standard C++ APIs will work fine for you as long as you stay inside the sandbox (this means you can't access files even in locations that are outside of sandbox but you have permission to them, such as music library). You can use most classic C/C++ libraries without issues as long as you do the interface with the runtime broker yourself. That means using windows runtime APIs instead of classic C APIs when dealing with stuff such as file access, for example. This is a pretty extensive topic and It is rather difficult to explain it all with 100% accuracy, especially when there is lots of docs running around.
You also get deterministic memory management, which is huge in specific scenarios.
Long story short
You will be fine with standard C/C++ when using
any in-memory functions supported by the compiler (you can manipulate data types, string, mutex, etc).
File IO in isolated storage only (applicationData folder)
Threads (although you are better off using threadpool or the like, it is much easier and cleaner). You can also use futures, and std::this_thread.
You will have to use winRT replacement
File system access in any other location than application data (you must use the windows::storage APIs)
sockets, internet access and the like.
any hardware related thing: music&video playerback must be interfaced through winRT (although the underlying decoders can be classic C/C++), messing around with the device sensors.
Retrieving system properties (internet connection state etc)
cross process communications
communicating with other apps
There are also win32 equivalents
mutex, threading, fileIO (isolated storage only)
Media playback with custom rendering pipeline.
Basically, winRT functions as an abstraction layer between the hardware and your code. You can use classic C++ up to the point where you need to interact with the system in any way. At that point, system interaction must be done with winRT. This way, microsoft ensures a higher degree of stability and security for devices.
check this link out for more information on the toolchains. You should be able to use this in VS 2013 as well with windows 8 (this is a compiler feature, has nothing to do with supported platform)
https://paoloseverini.wordpress.com/2014/04/22/async-await-in-c/

Categories

Resources