My interpretation of the problem
You should avoid designs which would require that your inner function needs that kind of knowledge (that is, from where it is called), whenever possible. For what follows, assume that the problem is set up as follows:
ClearAll[f,ff,g,h,codeBefore,codeAfter];
f[]:= Module[{},codeBefore;g[]; codeAfter];
ff[]:= Module[{},codeBefore;g[]; codeAfter];
g[]:= Module[{},codeBefore;h[]; codeAfter];
h[]:= (Some code that needs needs to know whether it is called inside f or ff)
Some ways out
Here are some different things you can do.
Pass arguments explicitly
One straightforward way of doing this is passing extra arguments explicitly:
ClearAll[f,ff,g,h,codeBefore,codeAfter];
f[]:= Module[{},codeBefore;g[f]; codeAfter];
ff[]:= Module[{},codeBefore;g[ff]; codeAfter];
g[fn_]:= Module[{},codeBefore;h[fn]; codeAfter];
h[fn_]:= Print["Called from ",fn];
which you test with e.g.
{f[], ff[]}
Use local dynamic environments (Block)
There are indeed cases where this is inconvenient, since you have to pass along the arguments which don't make sense for intermediate functions in the chain. In such cases, I sometimes use a global variable (say, $environment), but set it semi-locally by using Block, so this would look like
ClearAll[f,ff,g,h,codeBefore,codeAfter];
f[]:= Block[{$environment = {f}},codeBefore;g[]; codeAfter];
ff[]:= Block[{$environment = {ff}},codeBefore;g[]; codeAfter];
g[]:= Module[{},codeBefore;h[]; codeAfter];
h[]:= Print["Called from ", $environment];
which you can test as
{f[],ff[]}
Use the Stack
This method is somewhat fragile, but sometimes you just have no choice. Here is how it may look like:
ClearAll[f, ff, g, h, codeBefore, codeAfter];
f[] := Module[{}, codeBefore; g[]; codeAfter];
ff[] := Module[{}, codeBefore; g[]; codeAfter];
g[] := Module[{}, codeBefore; h[]; codeAfter];
h[] := Print[Stack[][[-9]]]
The problem here is that this will work only if you wrap the code you execute in StackComplete:
StackComplete[{f[], ff[]}]
During evaluation of In[112]:= f
During evaluation of In[112]:= ff
(* {codeAfter, codeAfter} *)
Remarks
Use explicit argument passing whenever possible. When not possible (although many cases where it does not look possible can be redesigned), use local environments. The uses of Stack should be reserved to cases when nothing else helps, and usually the code using Stack looks like a hack, so I'd avoid that if at all possible.
At the same time, I'd like to acknowledge that the problem raised here does indeed exist in practice. The real problem here is that often we would like to pass some parameters from the top-level function f directly to functions much lower down in the execution stack, while by-passing intermediate functions in the function call chain. One good reason to do that may be that those intermediate functions would have to be over-specialized to carry those parameters along, which would hurt re-usability. What I usually do is to try strike a right balance between the lexical and dynamic scoping (variable passing), with the preference given to lexical scoping but keeping an open mind and using local dynamic environments where appropriate.